GroovyInterceptable (AOP) and closures - grails

I've got a grails app with Service classes that inherit from Groovy's GroovyInterceptable:
class customerSerrvice implements GroovyInterceptable {
private List<Customer> customers
def invokeMethod(String name, args) {
log.debug "=======>INVOKING method [$name] with args:$args"
}
void foo() {
customers.each { doSomething(it) }
}
void doSomething(Customer cust) { log.debug "doSomething invoked with $cust" }
}
The above is a greatly simplified representation, but it gives you the idea. If I call foo() or doSomething() directly from another class, the invokeMethod gets called like it is supposed to. However, when foo() calls doSomething(), that call is not intercepted in invokeMethod.
If I change from
customers.each { doSomething(it) }
to
for(Customer cust: customers) { doSomething(cust) }
then the invokeMethod gets called just fine.
So is there something about closures and GroovyInterceptable that don't go together? Is there any way to get the invokeMethod to work with closures short of changing them all out?
Thanks

Confirmed as a bug, old link:
http://jira.codehaus.org/browse/GROOVY-4610, new link:
https://issues.apache.org/jira/browse/GROOVY-4610

Related

How to call a second ancestor method in Dart

Is it possible to call a second ancestor method in dart? something like super.super.hello()? If it's possible, how can it be written?
class A {
void hello() {
print('A');
}
}
class B extends A {
#override
void hello() {
print('B');
}
}
class C extends B {
#override
void hello() {
// How to call the hello() implemented in the class A here?
}
}
void main() {
var c = C();
c.hello();
}
It's not possible.
The reason it's not possible is that it breaks abstraction.
When you look at class C extend B, all you need to know about B is which signatures its members has and which interfaces it implements. As long as that stays effectively the same, your valid code will keep working.
Consider what would happen if the author of B decided to make themselves a helper base-class:
abstract class _BaseB extends A {
String get _myName;
#override
void hello() {
print(_myName);
}
}
class B extends _BaseB {
#override
String get _myName => "B";
}
That's a perfectly valid refactoring. The resulting class B has all the same members and implements all the same interfaces (and also _BaseB, but it's private so nobody can see that).
The C class above would keep working if all it does is to call super.hello(). If it had a way to ask for super.super.hello(), that might no longer be valid.
Similarly if the B class was changed to:
class B implements A {
#override
void hello() {
print("B");
}
}
(changing extends to implements), then all methods of B works the same as before and it implements the same interfaces. Again, there is no visible differences to the users of the B class.
But if you could call something like A.super.hello() to reach the A class's hello method, then that would now break because that method isn't in the B class at all.
So, by restricting super.hello() to only call methods on the precise class you write as the superclass, you are prevented from introducing dependencies on the implementation of B, dependencies which would make otherwise valid refactorings into breaking changes.

How to use get keyword as a class instance method name?

I know that get is one of the keywords in Dart, but I wanna wrap an HTTP client class with an instance method named get in my flutter app, it's semantic。 How can I do this?
Works for me:
void main() {
Http().get('');
}
class Http {
String get(String list) {
print('get called');
}
}
Maybe this will help
class HttpClient {
HttpClient.get() {
...
}
}

Groovy metaclass, mocking a service method that has throws clause

I have an abstract service:
abstract class ParentService {
abstract Map someMethod() throws NumberFormatException
}
And another service that extends above class:
class ChildService extends ParentService {
#Override
Map someMethod() throws NumberFormatException {
//Business Logic
}
}
I want to mock someMethod() using groovy metaClass. I need to mock this method for writing test cases for ChildService. This is what I have done for mocking:
ChildService.metaClass.someMethod = { -> "Mocked method" }
But this is not working and the call always executes actual method from the service. What needs to be done here? Am I missing something?
Please Note that I have to mock just one method not the entire service.
Maybe you could just mock method on instance?
def child = new ChildService()
child.metaClass.someMethod = { -> "Mocked method" }

In Dart, how do I get code completion when using noSuchMethod?

I'd like to use noSuchMethod to reduce boilerplate when writing a lot of similar methods. But then the API is worse for my library's users because code completion no longer works. I tried this but I get warnings about unimplemented methods:
class ThingMixin {
foo();
bar();
noSuchMethod(Invocation inv) {
...
}
}
Is there a workaround?
The trick is to define the API in a separate class:
abstract class ThingApi {
foo();
bar();
}
class ThingMixin implements ThingApi {
noSuchMethod(Invocation inv) {
...
}
}
(Note that noSuchMethod cannot call super if you want it to work as a mixin.)

php5 --- method visibility issue

Please have a look at below given code.
<?php
class Bar
{
public function test() {
$this->testPrivate();
$this->testPublic();
}
public function testPublic() {
echo "Bar::testPublic\n";
}
private function testPrivate() {
echo "Bar::testPrivate\n";
}
}
class Foo extends Bar
{
public function testPublic() {
echo "Foo::testPublic\n";
}
private function testPrivate() {
echo "Foo::testPrivate\n";
}
}
$myFoo = new foo();
$myFoo->test(); // Bar::testPrivate
// Foo::testPublic
?>
In above example, when we called $myFoo->test();it called testPrivate of Bar class
But how come it called testPublic of Foo class.
Can any one help me in this ?
Bar.testPrivate and Foo.testPrivate have to be protected methods instead of private ones. See here for more:
http://php.net/manual/en/language.oop5.visibility.php
Because test() is NOT in Foo and is running in Bar scope. Bar scope can't access to Foo private methods.
Just add test() to Foo...
Indeed one of the comments on the visibility page does reiterate this:
"private methods never participate in the in the overriding because these methods are not visible in the child classes."
It does feel a bit strange because you would think that the child class would override the parent with the method names being the same, but its not the case with private methods and the parents method takes precidence here, so best to use protected methods if you want to override.

Resources