execute code before calling parent constructor in dart - dart

I'm starting on dart and I want to know if there is any way to execute code before calling the constructor of a parent class.
I have a class that inherits from another and I want to execute code on one of the parameters that I have to pass to the parent class.
this is what i have
MyOption(final List<String> opts,Map<String,dynamic>
attrs):super(opts,attrs){
this.my_default = attrs['my_default'];
}
and this is what i want (python code):
def __init__(self, *opts, **attrs):
self.my_default = attrs.pop('my_default', None)
super(MyOption, self).__init__(*opts, **attrs)
As you can see, I need to delete an element from the list before passing it as a parameter to the constructor of the parent class.
Can it be done in dart?

MyOption(final List<String> opts,Map<String,dynamic> attrs): this.my_default = attrs.remove('my_default'),super(opts,attrs){
//this.my_default = attrs['my_default'];
}
Thank you.

Related

Access side input in a non - anonymous DoFn

How to access the elements of a side input if I have my class extend DoFn?
For example:
Say I have a ParDo transform like:
PCollection<String> data = myData.apply("Get data",
ParDo.of(new MyClass()).withSideInputs(myDataView));
And I have a class:-
static class MyClass extends DoFn<String,String>
{
//How to access side input here
}
c.sideInput() isn't working in this case.
Thanks.
In this case, the problem is that the processElement method in your DoFn does not have access to the PCollectionView instance in your main method.
You can pass the PCollectionView to the DoFn in the constructor:
class MyClass extends DoFn<String,String>
{
private final PCollectionView<..> mySideInput;
public MyClass(PCollectionView<..> mySideInput) {
// List, or Map or anything:
this.mySideInput = mySideInput;
}
#ProcessElement
public void processElement(ProcessContext c) throws IOException
{
// List or Map or any type you need:
List<..> sideInputList = c.sideInput(mySideInput);
}
}
You would then pass the side input to the class when you instantiate it, and indicate it as a side input like so:
p.apply(ParDo.of(new MyClass(mySideInput)).withSideInputs(mySideInput));
The explanation for this is that when you use an anonymous DoFn, the process method has a closure with access to all the objects within the scope that encloses the DoFn (among them is the PCollectionView). When you're not using an anonymous DoFn, there is no closure, and you need another way of passing the PCollectionView.
So although the answer above is correct, it is still a little incomplete.
So once you finish implementing the above answer, you need to execute your pipeline like this:
p.apply(ParDo.of(new MyClass(mySideInput)).withSideInputs(mySideInput));

How to test logic in constructor?

My test class like this:
public class HandlerTest extends Specification {
Handler hander
EventBus eventBus=Mock()
def setup(){
handler=new Handler(eventBus)
}
def "constructor"(){
//How to verify two events do get added to eventBus?
}
}
and Constructor of Handler(it is a java class)
public Handler(EventBus eventBus)
{
eventBus.add(FetchSearchWordsEvent.TYPE, this);
eventBus.add(SetSearchBoxTextEvent.TYPE, this);
}
Question is:
how to verify that two events do get registered?
I would move the call to Handler constructor into the test itself given that it is the function under test.
Try the following:
public class HandlerTest extends Specification {
Handler hander
def mockEventBus = Mock(EventBus)
def "constructor"(){
when:
new Handler(mockEventBus)
then:
1 * mockEventBus.add(FetchSearchWordsEvent.TYPE, _ as Handler)
1 * mockEventBus.add(SetSearchBoxTextEvent.TYPE, _ as Handler)
}
}
The functionality of EventBus.add() should be tested separately.
It depends on how registerHandler is implemented, and what exactly you want to verify. If the goal is to verify that the constructor ultimately calls some methods on eventBus, you can just use regular mocking. If the goal is to verify that the constructor calls registerHandler on itself, you can use partial mocking using Spy(), as explained in the Spock reference documentation.
PS: Note that partial mocking is considered a smell. Often it's better to change the class under test to make it easier to test. For example, you could add a method that allows to query which handlers have been registered. Then you won't need mocking at all.

in Dart, problems when attempting to "register" sub-class with super-class

I wish to have the sub-classes of a super-class "registered" by an arbitrary name - whenever I declare a sub-class I wish to also have it entered into the super-class.sub Map.
Is there any way to accomplish this outside of main()?
// base class
class Mineral{
final String formula;
static Map<String,Mineral> sub = {}
Mineral( this.formula );
}
// sub class - declare and register
class Mica extends Mineral{
Mica( String formula ) : super( formula );
}
Mineral.sub['mica'] = Mica; // oops!
when I run this, I get
Error: line 10 pos 1: unexpected token 'Mineral' Mineral.sub['mica'] = Mica;
assuming that executable code is not allowed outside main().
cannot put within the super-class since other sub-classes may declared later, outside the library.
Dart has no way to run code as part of a library being loaded.
Executable code can only be put inside methods, or in field initializers, and static field initializers are lazy so they won't execute any code until you try to read them.
This is done to ensure quick startup - a Dart program doesn't have to execute any code before starting the main library's "main" method.
So, no, there is no way to initialize something that isn't constant before main is called.
Either
Mineral.sub['mica'] = new Mica();
or
static Map<String,Type> sub = {};
When you assign Mica you assign the Type Mica. new Mica() is an instance of Mica that is of the kind Mineral and can be assigned to the map you declared.
edit
Maybe you want to initialize the sub map:
static Map<String,Mineral> sub = {'mica': new Mica()};
hint: the semicolon is missing in this line in your question.

Using mirrors, how can I get a reference to a class's method?

Say I have an instance of a class Foo, and I want to grab a list of all of its methods that are annotated a certain way. I want to have a reference to the method itself, so I'm not looking to use reflection to invoke the method each time, just to grab a reference to it the first time.
In other words, I want to do the reflection equivalent of this:
class Foo {
a() {print("a");}
}
void main() {
var f = new Foo();
var x = f.a; // Need reflective way of doing this
x(); // prints "a"
}
I have tried using InstanceMirror#getField, but methods are not considered fields so that didn't work. Any ideas?
As far as I understand reflection in Dart, there's no way to get the actual method as you wish to. (I'll very happily delete this answer if someone comes along and shows how to do that.)
The best I can come up with to ameliorate some of what you probably don't like about using reflection to invoke the method is this:
import 'dart:mirrors';
class Foo {
a() {print("a");}
}
void main() {
var f = new Foo();
final fMirror = reflect(f);
final aSym = new Symbol('a');
final x = () => fMirror.invoke(aSym, []);
x(); // prints "a"
}
Again, I know that's not quite what you're looking for, but I believe it's as close as you can get.
Side note: getField invokes the getter and returns the result -- it's actually fine if the getter is implemented as a method. It doesn't work for you here, but for a different reason than you thought.
What you're trying to get would be described as the "closurized" version of the method. That is, you want to get the method as a function, where the receiver is implicit in the function invocation. There isn't a way to get that from the mirror. You could get a methodMirror as
reflect(foo).type.methods[const Symbol("a")]
but you can't invoke the result.

Struts2 annotation with parameter when using json plugin

Simply I want to evaluate a property of my action and use it's value within an annotation.
The following is exactly where I want to use it.
I want to define a excludeProperties parameter at run time.
Consider the following annotation which currently works on the action:
#Result(name = "success", type = "json", params = {"root", "model", "excludeProperties", "myCollection"})
There the actions model has a myCollection collection which I do not want serialized.
However I would like to create an exclusion String (a string will do for now).
If I create a getter setter for exclusion, I would expect the following annotation to work (which does not):
#Result(name = "success", type = "json", params = {"root", "model", "excludeProperties", "${exclusion}"})
Any ideas?
I have created actions similar to this answer which shows resolving a parameter within an annotation. I am using the named variable pattern matcher to extract values from the namespace... but I just can't seem to set this parameter no matter what I do.
Part of the issue was that I was working with entity objects and serializing collections was an issue. With your own custom JSON result type you can do what ever you want. Since created getter setter for jsonModel, I just constructed what I needed there. I don't need to worry about lazy initialization errors because you need to explicitly include collections with flexjson so if you just want the primitives (which I did) then flexjson is perfect.
This very simple result type using flexjson which worked for my needs:
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.Result;
import com.opensymphony.xwork2.util.ValueStack;
import flexjson.JSONSerializer;
import java.io.PrintWriter;
import org.apache.struts2.ServletActionContext;
public class Kjson implements Result {
#Override
public void execute(ActionInvocation invocation) throws Exception {
ServletActionContext.getResponse().setContentType("text/plain");
PrintWriter responseStream = ServletActionContext.getResponse().getWriter();
ValueStack valueStack = invocation.getStack();
Object jsonModel = valueStack.findValue("jsonModel");
//create json and put it into response stream
responseStream.println(new JSONSerializer().exclude("class").serialize(jsonModel));
}
}

Resources