Mono: flatMap to load another item then return original item - spring

I am just starting with Spring Webflux and I was wondering if the following call is a good way to load additional items in a reactive stream and if there is maybe another operator that can simplify this call:
Mono<Foo> fooMono = fooService.loadFoo();
fooMono.flatMap(foo -> barService.loadBarForFoo(foo).flatMap(bar -> Mono.just(foo)))
For example: fooMono might be something loaded via a WebClient and barService.loadBarFromFoo would know how to load a Bar given a Foo and then insert bar into foo. In the end I want to get foo back to perform some more actions, like loading another resource into foo.
Is it good practice to create a new Mono from foo in the end or is there maybe even another operator that can be used to simplify this?

Hi you could use thenReturn supposing you do not need to use the result of loadBarForFoo method.
fooMono.flatMap(foo -> barService.loadBarForFoo(foo).thenReturn(foo));

Related

How to check where a who calls this method?

I have a custom method in an ABAP class.
I used the 'Where used' tool to show where the class is called from but, as it turns out, it's called from somewhere else I didn't expect.
So what's the best way of showing a complete list of everything that calls the method?
Due to the wonders of object-oriented programming, an instance of a class can hide behind a reference to one of its base classes or interfaces it implements. For example:
DATA foo TYPE REF TO z_my_interface.
CREATE OBJECT foo TYPE z_my_class.
" lots of more code
foo->bar( ).
You can not find this reference to z_my_class->foo with its "Where Used" list, because at that code location foo could also be a reference to an instance of any other class which implements z_my_interface. But you might be able to find this if you don't just look at the where-used list of the method but at the where-used list of the whole class or the interface / base class which declares the method.
And then there are evil dynamic programming tricks like this which determine methods and classes at runtime:
DATA foo TYPE REF TO object.
CONSTANTS: classname TYPE string VALUE 'Z_MY_CLASS',
methodname TYPE string VALUE 'BAR'.
CREATE OBJECT foo TYPE (classname).
CALL METHOD foo->(methodname).
There is no chance to find this with the where-used tool. But if the class- and/or method name does actually appear in the code (it might not, for example if they are read from a customizing table) then you can use the report RS_ABAP_SOURCE_SCAN. This handy little tool allows you to select a set of ABAP programs and search for strings (and even regular expressions) within their sourcecodes.
However, if you know the method gets called when you do something specific as a user and just want to know where, then it can be easier to just set a debugger breakpoint in the method, run into it and check the call stack.
Sorted using the code_scanner transaction.

Object validation using builder pattern

Let's say I have an object Foo. I also have an FooBuilder which is to be used to construct the Foo objects. When and where should I validate the Foo object's data?
Foo foo = new FooBuilder()
.withX("specific data for X")
.withY("specific data for Y")
.build();
Let's add to the equation that the validation may contain lookups in for example a database. Should the builder perform a validation inside the build method? Or should there be a specific validate method in the foo object? Or maybe the validation is best off completely abstracted from both the Foo object and the FooBuilder?
Ideally it should not be possible to create an invalid Foo object at all. Therefore having a validation method in Foo is not the best choice.
The validation should be done as early as possible. This could be in the build() method or - if possible - even earlier within the setter methods of the builder.
If you should put the actual implementation of your validator into the builder or into a separate class depends its complexity. If it requires things like database lookups, as you mentioned, it probably makes sense to create a separate validation class.
I like to add that the builder is sometimes considered an antipattern indicating that the class is probably too complex and should be split into multiple smaller classes.

Caching the result of all methods

I have a class which is essentially a collection of methods for some data transformations. In another words I have some data in my files and I use a few different code snippets to transform the textual data into something that I can easily query.
Now the methods often reuse each-other and as the core data is changing I'd like to simply cache the results of each method, for the speed reasons.
I don't want to change each method by adding:
^ methodsCache ifNil: [ methodsCache := "compute" ]
I want to use the power of Pharo reflection to accomplish my task without touching much of code.
One idea that I had is if I can run some code before each method, thing I can either return a cached value or continue the execution of the method and cache it's result
You could use the Reflectivity framework to add pre and post meta links to your methods. A link could check a cache before execution transparently.
link := MetaLink new
metaObject: self;
selector: #cachedExecute:;
arguments: #(selector);
control: #before.
(MyClass>>#myMethodSelector) ast link: link.
This code will install a meta link that sends #cachedExecute: to a MyClass object with the argument #myMethodSelector. The link is installed on the first AST node of the compiled method (of that same method selector, but could be on another method). The #control: message ensures that the link will be executed before the AST node is executed.
You can of course install multiple meta links that influence each other.
Note that in the above example you must not send the same message (#myMethodSelector) again inside of the #cachedExecute: method since you'd end up in a loop.
Update
There's actually an error in the code above (now fixed). The #arguments: message takes a list of symbols that define the parameters of the method specified via #selector:. Those arguments will be reified from the context. To pass the method selector you's use the #selector reification, for the method context the #context reification and for method arguments #arguments. To see which reifications are available, look at the #key on the class side of the subclasses of RFReification.
One idea that I had is to define
doesNotUnderstand: aMessage
aMessage selector beginsWith: 'cached' ifFalse: [ ^ super doesNotUnderstand: aMessage ].
^ cache at: aMessage selector ifAbsentPut: [
self perform: aMessage selector allButFirst: 6 ]
This way the only thing you have to do is to replace all message sends like self methodName with self cachedmethodName (or self cachedMethodName but then you have to do additional lowercase workaround in doesNotUnderstand:)
Another well-known option would be to replace your new and return a caching proxy, delegating to the actual object

Storing the results of Html.Action call in a dictionary? (ASP.NET MVC 3)

I'm working on an ASP.NET MVC3 app, and I'd like to make a call from the view to the controller and store that information as a Dictionary.
Controller code:
public Dictionary<string,int> foo()
{
Dictionary<string,int> bar = new Dictionary<string,int>();
bar.Add("test",100);
return bar;
}
View code:
#{ Dictionary<string,int> foobar = Html.Action("foo"); }
...
<div>#foobar["test"]</div>
I can get the view to work if I use var foobar = Html.Action("foo");, but then it just says that foobar is of type System.Web.Mvc.MvcHtmlString, so I can't do much with it.
Is there any built-in functionality that I'm missing, or should I just use something like a JSON result for this?
EDIT: Additional Info
It should be noted also, that in the VS2010 debugger, it recognizes foobar properly as {System.Collections.Generic.Dictionary'2[System.String,System.Int32]}, so the issue is that foobar isn't resolving correctly. The error thrown is:
Compiler Error Message: CS0021: Cannot apply indexing with []
to an expression of type 'System.Web.Mvc.MvcHtmlString'
EDIT 2
These are the errors that came with casting the result to a dictionary:
Url.Action("foo").ToDictionary<string,int>(); returned CS1501: No overload for method 'ToDictionary' takes 0 arguments for obvious reasons, but the VS2010 debugger recognizes that the result is a Dictionary:
But when I add parameters (Url.Action("foo").ToDictionary<string,int>(x=>x);), it stops recognizing that it is a dictionary, although I'm not sure those are the proper params (it's based off what I found here.
You should try as much as possible to keep views dumb. The controller has to push the data to the view. For some reason if you want to perform call a function that performs complex calculations then a better idea would be create a separate static class and move the function from controller to that class. The Html.Action is for entirely a different purpose. Your controllers should always return action results not dictionaries or other types.
A call to Html.Action("foo") is supposed to return a string. What this is doing is calling an action method that renders the child view as a string. See http://msdn.microsoft.com/en-us/library/ee721266
You could call a static utility method , see Is this an Extension or Helper Method in MVC3?

Replace method call to another

I need to replace all the ocurances of obj.Method1() to obj.Method2() where obj is an instances of the same class. Does ReSharper or VS2010 allow this?
You could write a ReSharper Replace Pattern (ReSharper->Tools->Pattern Catalog, Add Pattern) like so:
where the type of expression obj needs to be changed to your class (that contains Method1).
Then press Save and thereafter press Search now to get all Method1() calls:
Then click Replace and all Method1 calls are type-safely replaced to Method2.
I'd cheat - Do a 3-point symbolic rename (Right-click->Rename on a method name)
Method1 -> Temp
Method2 -> Method1
Temp -> Method2
None of this will change code functionality but will update all your code to use the correct name, except the methods themselves are now named incorrectly - simply rename the methods to by hand and voila - A little bit hacky but fast and effective.
This does rely on all method calls being in managed code (so that VS knows how/what to rename). If you have XML comments, C# rename handles this well but VB doesn't - I assume since you mention ReSharper, you're using C#?
This also assumes the method signatures are identical (if not, get ready for a lot of copy/pasting)
Make body of Method1 like this
public void Method1(...) { return Method2(...); }
And invoke refactoring "Inline method" on Method1.

Resources