groovy-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Marc Paquette <mar...@mac.com>
Subject Re: Problem using 'is' in a command chain
Date Thu, 29 Oct 2015 05:30:01 GMT

> Le 2015-10-28 à 21:40, Edinson E. Padrón Urdaneta <edinson.padron.urdaneta@gmail.com>
a écrit :
> 
> I'm sorry mate. That happens when you code at midnight in a polluted groovysh. Try this
out:
> 

I don’t know what you are talking about ;-)

> def check(condition) {
>   // Define and initialize a new map
>   def map = [:]
> 
>   // Replace the `is` method from the map's metaclass
>   map.getMetaClass().is = { bool ->
>       println "checking if $condition yields $bool, with 'is'"
>   }
> 
>   // Return the map
>   map
> }
> 

Brillant !  I have to say I'm surprised that `map.getMetaClass().is = ...` only changes that
map's metaClass, i.e. I expected it to change the `metaClass` instance of the `Map` class,
not the `metaClass` instance of a (single) `Map` instance.  

I wonder if this is an accident or designed that way ?

If it is by design, then that's very good for the purpose of a dsl as 1) `is` can then be
used, 2) with your technique, the metaclass manipulation is local to the Map instance created
in the chained method definition, therefore I don't have to compromise on hiding Groovy to
my DSL (as Jason explained).

In summary, to support the command expression

   every 'member' of 'family' is 'adult'

my chained method definition is :

def every(member) {
    [of: { what ->
        def map = [:]
        map.getMetaClass().is = { value ->
           println "every - of - is : $member, $what, $value"
        }
        map
    }]
}

Running it yields the expected result :

every - of - is : member, family, adult

Granted, writing the chained method definition is a little more tricky, partly because one
have to be careful of dynamic scoping for `member` and `what`, but the net result is very
nice.

Thank you very much for your ideas !

Marc

> 
> On Wed, Oct 28, 2015 at 8:31 PM, Marc Paquette <marcpa@mac.com <mailto:marcpa@mac.com>>
wrote:
> Your suggestion seemed promising, but I can’t make it work :
> 1) `map.metaClass` is null
> 2) `map.getClass().metaClass.is <http://metaclass.is/> = null` or `Map.metaClass.is
<http://map.metaclass.is/> = null` does not remove the `is` method
> 3) `map[is]` gives `Caught: groovy.lang.MissingPropertyException: No such property: is
for class: …`
> 
> I am curious, you said « but it works », what version of groovy (groovy --version)
did you use ?
>  
> 
>> Le 2015-10-28 à 01:08, Edinson E. Padrón Urdaneta <edinson.padron.urdaneta@gmail.com
<mailto:edinson.padron.urdaneta@gmail.com>> a écrit :
>> 
>> If you want to use `is` in your DSL you could try:
>> 
>> def check(condition) {
>>   // Define and initialize a new map
>>   def map = [:]
>> 
>>   // Remove the `is` method from the map's metaclass
>>   map.metaClass.is <http://map.metaclass.is/> = null
>> 
>>   // Add the key-value pair we care for the DSL
>>   map[is] = { bool ->
>>       println "checking if $condition yields $bool, with 'is'"
>>   }
>> 
>>   // Return the map
>>   map
>> }
>> 
>> I don't know if the above follows good practices or at very least is a good idea
(remember that I'm very new) but it works.
>> 
>> 
>> On Wed, Oct 28, 2015 at 12:19 AM, Edinson E. Padrón Urdaneta <edinson.padron.urdaneta@gmail.com
<mailto:edinson.padron.urdaneta@gmail.com>> wrote:
>> Well, I'm very new to groovy so I could be very wrong but `is` is a method of `GroovyObjectSupport`,
so maybe you are invoking that method in your DSL without knowing that.
>> 
>> On Tue, Oct 27, 2015 at 10:47 PM, Marc Paquette <marcpa@mac.com <mailto:marcpa@mac.com>>
wrote:
>> Playing with DSL here (going through chapter 19 of « Groovy In Action, second edition
», well worth the read).  It seems that one cannot use the word ‘is’ to build a command
chain dsl, but ‘IS’ or ‘Is’ or ‘iS’ are ok… Or is it something I’m doing wrong
?
>> 
>> ```
>> [marcpa@MarcPaquette dsl]$ groovy --version
>> Groovy Version: 2.4.3 JVM: 1.8.0_60 Vendor: Oracle Corporation OS: Mac OS X
>> [marcpa@MarcPaquette dsl]$ cat chainWithLowerCaseIsFails.groovy
>> def check(condition) {
>>     [is: { bool ->
>>         println "checking if $condition yields $bool, with 'is'"
>>     },
>>     IS: { bool ->
>>         println "checking if $condition yields $bool, with 'IS'"
>>     }]
>> }
>> 
>> cond = (1<2)
>> check cond is true
>> check cond IS true
>> [marcpa@MarcPaquette dsl]$ groovy chainWithLowerCaseIsFails.groovy
>> checking if true yields true, with 'IS'
>> [marcpa@MarcPaquette dsl]$
>> ```
>> 
>> Marc Paquette
>> 
>> 
>> 
> 
> 


Mime
View raw message