You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@groovy.apache.org by Gerald Wiltse <je...@gmail.com> on 2016/04/20 07:07:37 UTC

Methods for Creating Ranges

I can find no examples of different ways to create a range.  There's a
plethora of examples on what you can do when you start by creating a range
like so:  "1..10"

But, how does one create a range when the min and max values are stored in
variables?  There's no range constructor.  I see that it's a form of a
list, but I see no helper methods for dynamically creating ranges given a
min and max value.

I even tried to get really fancy, but this evaluates to a string.

def v = "10..15"
assert Eval.x(v, "return x")​.getClass()​.name ==
"​​​​​​​​​​​java.lang.String"​

My use case is this.  I populate a bunch of form fields with variable
definitions... but they all get passed to my code as strings. But I want to
pass port ranges and lists and maps. So, the Eval() method is exactly what
I needed.. it just isn't working for ranges.

Regards,
Jerry


Gerald R. Wiltse
jerrywiltse@gmail.com

Re: Methods for Creating Ranges

Posted by Gerald Wiltse <je...@gmail.com>.
Scratch the part about the side effect... i forgot to remove that line
after adding the exception handling.

Gerald R. Wiltse
jerrywiltse@gmail.com


On Wed, Apr 20, 2016 at 2:31 AM, Gerald Wiltse <je...@gmail.com>
wrote:

> For posterity, here's the working form of very short loop for accepting a
> bunch of values in a map which are all in string form.  The goal is to try
> to parsing them to their groovy types, and then assign them to the
> variables on the current object if those variables exist.  This loop will
> be in the constructor for various objects that get "instantiated" from this
> source application.  The exception is needed for plain old string values.
>
> taskProps.each {String k,String v ->
>     if (this.hasProperty(tmpKey)) {
>         try{
>             this[tmpKey] =  new GroovyShell().parse(v).run()
>         }catch(MissingPropertyException e){
>             this[tmpKey] = v
>         }
>     }
> }
>
> Groovy really is amazing.
>
>
> It seems the one side-effect is that all string properties will now have
> to be enclosed in quotes, whereas before they did not.
>
> Here are the proofs... Maybe mrhaki can post these examples on his blog.
>
> def r = "1..5"
> assert new GroovyShell().parse("return $r").run() == [1, 2, 3, 4, 5]
>
> def b = "true"
> assert new GroovyShell().parse("return $b").run() == true
>
> def l = "['str1','str2']"
> assert new GroovyShell().parse("return $l").run() == ['str1', 'str2']
>
> def s = "'mystring'"
> assert new GroovyShell().parse("return $s").run() == "mystring"
>
> ​def m = "['key1':'value1','key2':'value2']"
> assert new GroovyShell().parse("return $m").run()​ ==
> ['key1':'value1','key2':'value2']​
>
> Gerald R. Wiltse
> jerrywiltse@gmail.com
>
>
> On Wed, Apr 20, 2016 at 1:57 AM, Gerald Wiltse <je...@gmail.com>
> wrote:
>
>> Also, thank you so very much for the response!
>>
>> Gerald R. Wiltse
>> jerrywiltse@gmail.com
>>
>>
>> On Wed, Apr 20, 2016 at 1:57 AM, Gerald Wiltse <je...@gmail.com>
>> wrote:
>>
>>> Wow, i just wrote that exact code basically... and started responding to
>>> your email, but there were various drawbacks to this approach as I don't
>>> want to have to define handling of every property by name...  Then... it
>>> hit me...
>>>
>>> def v = '1..10'
>>> assert new GroovyShell().parse(v).run() == [1,2,3,4,5]
>>>
>>> It works!!!
>>>
>>> Something about the Eval works just a little bit differently than
>>> GroovyShell i guess.  Perhaps Dierk  can explain.
>>>
>>> Last question, how expensive is this invocation of groovyshell and parse
>>> and all that (resources wise)?  So-so?
>>>
>>>
>>> Gerald R. Wiltse
>>> jerrywiltse@gmail.com
>>>
>>>
>>> On Wed, Apr 20, 2016 at 1:48 AM, Guillaume Laforge <gl...@gmail.com>
>>> wrote:
>>>
>>>> If you know it's a range when parsing that string, you can do this,
>>>> with the toInteger() method:
>>>>
>>>>    def rangeString = "123..455"
>>>>    def (String min, String max) = rangeString.tokenize("..")
>>>>    def range = min.toInteger()..max.toInteger()
>>>>
>>>> On Wed, Apr 20, 2016 at 7:26 AM, Gerald Wiltse <je...@gmail.com>
>>>> wrote:
>>>>
>>>>> I don't see how that works in my case, maybe i'm missing something.
>>>>>
>>>>> I will clarify:
>>>>>
>>>>> I define a variable in web to represent the range:   14502..14520
>>>>>
>>>>> The web converts this to a string, and passes it into my code.
>>>>>
>>>>> My code then has to receive this string, and then construct a list
>>>>> from it.
>>>>>
>>>>> I could do:
>>>>>
>>>>> String rangeString = passedInVar
>>>>> (String min, String max) = rangeString.tokenize("..")
>>>>> Range range = min..max
>>>>>
>>>>> But i was hoping for a universal "caster" loop which can detect and
>>>>> cast the common types from strings:
>>>>> Integers, lists, ranges, maps, booleans..
>>>>>
>>>>> 12345
>>>>> ["this", "is", "Sample", "List"]
>>>>> 14502..14520
>>>>> ["key":"value","for":"maps"]
>>>>> true
>>>>>
>>>>> I think eval works for all but ranges.
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> Gerald R. Wiltse
>>>>> jerrywiltse@gmail.com
>>>>>
>>>>>
>>>>> On Wed, Apr 20, 2016 at 1:15 AM, Guillaume Laforge <glaforge@gmail.com
>>>>> > wrote:
>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> You can just replace the bounds with variables.
>>>>>>
>>>>>> def a = 1
>>>>>> def b = 10
>>>>>> def r = a..b
>>>>>>
>>>>>> Isn't that what you're looking for?
>>>>>>
>>>>>> Guillaume
>>>>>>
>>>>>>
>>>>>> Le mercredi 20 avril 2016, Gerald Wiltse <je...@gmail.com> a
>>>>>> écrit :
>>>>>>
>>>>>>> I can find no examples of different ways to create a range.  There's
>>>>>>> a plethora of examples on what you can do when you start by creating a
>>>>>>> range like so:  "1..10"
>>>>>>>
>>>>>>> But, how does one create a range when the min and max values are
>>>>>>> stored in variables?  There's no range constructor.  I see that it's a form
>>>>>>> of a list, but I see no helper methods for dynamically creating ranges
>>>>>>> given a min and max value.
>>>>>>>
>>>>>>> I even tried to get really fancy, but this evaluates to a string.
>>>>>>>
>>>>>>> def v = "10..15"
>>>>>>> assert Eval.x(v, "return x")​.getClass()​.name ==
>>>>>>> "​​​​​​​​​​​java.lang.String"​
>>>>>>>
>>>>>>> My use case is this.  I populate a bunch of form fields with
>>>>>>> variable definitions... but they all get passed to my code as strings. But
>>>>>>> I want to pass port ranges and lists and maps. So, the Eval() method is
>>>>>>> exactly what I needed.. it just isn't working for ranges.
>>>>>>>
>>>>>>> Regards,
>>>>>>> Jerry
>>>>>>>
>>>>>>>
>>>>>>> Gerald R. Wiltse
>>>>>>> jerrywiltse@gmail.com
>>>>>>>
>>>>>>>
>>>>>>
>>>>>> --
>>>>>> Guillaume Laforge
>>>>>> Apache Groovy committer & PMC Vice-President
>>>>>> Product Ninja & Advocate at Restlet <http://restlet.com>
>>>>>>
>>>>>> Blog: http://glaforge.appspot.com/
>>>>>> Social: @glaforge <http://twitter.com/glaforge> / Google+
>>>>>> <https://plus.google.com/u/0/114130972232398734985/posts>
>>>>>>
>>>>>>
>>>>>
>>>>
>>>>
>>>> --
>>>> Guillaume Laforge
>>>> Apache Groovy committer & PMC Vice-President
>>>> Product Ninja & Advocate at Restlet <http://restlet.com>
>>>>
>>>> Blog: http://glaforge.appspot.com/
>>>> Social: @glaforge <http://twitter.com/glaforge> / Google+
>>>> <https://plus.google.com/u/0/114130972232398734985/posts>
>>>>
>>>
>>>
>>
>

Re: Methods for Creating Ranges

Posted by Gerald Wiltse <je...@gmail.com>.
For posterity, here's the working form of very short loop for accepting a
bunch of values in a map which are all in string form.  The goal is to try
to parsing them to their groovy types, and then assign them to the
variables on the current object if those variables exist.  This loop will
be in the constructor for various objects that get "instantiated" from this
source application.  The exception is needed for plain old string values.

taskProps.each {String k,String v ->
    if (this.hasProperty(tmpKey)) {
        try{
            this[tmpKey] =  new GroovyShell().parse(v).run()
        }catch(MissingPropertyException e){
            this[tmpKey] = v
        }
    }
}

Groovy really is amazing.


It seems the one side-effect is that all string properties will now have to
be enclosed in quotes, whereas before they did not.

Here are the proofs... Maybe mrhaki can post these examples on his blog.

def r = "1..5"
assert new GroovyShell().parse("return $r").run() == [1, 2, 3, 4, 5]

def b = "true"
assert new GroovyShell().parse("return $b").run() == true

def l = "['str1','str2']"
assert new GroovyShell().parse("return $l").run() == ['str1', 'str2']

def s = "'mystring'"
assert new GroovyShell().parse("return $s").run() == "mystring"

​def m = "['key1':'value1','key2':'value2']"
assert new GroovyShell().parse("return $m").run()​ ==
['key1':'value1','key2':'value2']​

Gerald R. Wiltse
jerrywiltse@gmail.com


On Wed, Apr 20, 2016 at 1:57 AM, Gerald Wiltse <je...@gmail.com>
wrote:

> Also, thank you so very much for the response!
>
> Gerald R. Wiltse
> jerrywiltse@gmail.com
>
>
> On Wed, Apr 20, 2016 at 1:57 AM, Gerald Wiltse <je...@gmail.com>
> wrote:
>
>> Wow, i just wrote that exact code basically... and started responding to
>> your email, but there were various drawbacks to this approach as I don't
>> want to have to define handling of every property by name...  Then... it
>> hit me...
>>
>> def v = '1..10'
>> assert new GroovyShell().parse(v).run() == [1,2,3,4,5]
>>
>> It works!!!
>>
>> Something about the Eval works just a little bit differently than
>> GroovyShell i guess.  Perhaps Dierk  can explain.
>>
>> Last question, how expensive is this invocation of groovyshell and parse
>> and all that (resources wise)?  So-so?
>>
>>
>> Gerald R. Wiltse
>> jerrywiltse@gmail.com
>>
>>
>> On Wed, Apr 20, 2016 at 1:48 AM, Guillaume Laforge <gl...@gmail.com>
>> wrote:
>>
>>> If you know it's a range when parsing that string, you can do this, with
>>> the toInteger() method:
>>>
>>>    def rangeString = "123..455"
>>>    def (String min, String max) = rangeString.tokenize("..")
>>>    def range = min.toInteger()..max.toInteger()
>>>
>>> On Wed, Apr 20, 2016 at 7:26 AM, Gerald Wiltse <je...@gmail.com>
>>> wrote:
>>>
>>>> I don't see how that works in my case, maybe i'm missing something.
>>>>
>>>> I will clarify:
>>>>
>>>> I define a variable in web to represent the range:   14502..14520
>>>>
>>>> The web converts this to a string, and passes it into my code.
>>>>
>>>> My code then has to receive this string, and then construct a list from
>>>> it.
>>>>
>>>> I could do:
>>>>
>>>> String rangeString = passedInVar
>>>> (String min, String max) = rangeString.tokenize("..")
>>>> Range range = min..max
>>>>
>>>> But i was hoping for a universal "caster" loop which can detect and
>>>> cast the common types from strings:
>>>> Integers, lists, ranges, maps, booleans..
>>>>
>>>> 12345
>>>> ["this", "is", "Sample", "List"]
>>>> 14502..14520
>>>> ["key":"value","for":"maps"]
>>>> true
>>>>
>>>> I think eval works for all but ranges.
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> Gerald R. Wiltse
>>>> jerrywiltse@gmail.com
>>>>
>>>>
>>>> On Wed, Apr 20, 2016 at 1:15 AM, Guillaume Laforge <gl...@gmail.com>
>>>> wrote:
>>>>
>>>>> Hi,
>>>>>
>>>>> You can just replace the bounds with variables.
>>>>>
>>>>> def a = 1
>>>>> def b = 10
>>>>> def r = a..b
>>>>>
>>>>> Isn't that what you're looking for?
>>>>>
>>>>> Guillaume
>>>>>
>>>>>
>>>>> Le mercredi 20 avril 2016, Gerald Wiltse <je...@gmail.com> a
>>>>> écrit :
>>>>>
>>>>>> I can find no examples of different ways to create a range.  There's
>>>>>> a plethora of examples on what you can do when you start by creating a
>>>>>> range like so:  "1..10"
>>>>>>
>>>>>> But, how does one create a range when the min and max values are
>>>>>> stored in variables?  There's no range constructor.  I see that it's a form
>>>>>> of a list, but I see no helper methods for dynamically creating ranges
>>>>>> given a min and max value.
>>>>>>
>>>>>> I even tried to get really fancy, but this evaluates to a string.
>>>>>>
>>>>>> def v = "10..15"
>>>>>> assert Eval.x(v, "return x")​.getClass()​.name ==
>>>>>> "​​​​​​​​​​​java.lang.String"​
>>>>>>
>>>>>> My use case is this.  I populate a bunch of form fields with variable
>>>>>> definitions... but they all get passed to my code as strings. But I want to
>>>>>> pass port ranges and lists and maps. So, the Eval() method is exactly what
>>>>>> I needed.. it just isn't working for ranges.
>>>>>>
>>>>>> Regards,
>>>>>> Jerry
>>>>>>
>>>>>>
>>>>>> Gerald R. Wiltse
>>>>>> jerrywiltse@gmail.com
>>>>>>
>>>>>>
>>>>>
>>>>> --
>>>>> Guillaume Laforge
>>>>> Apache Groovy committer & PMC Vice-President
>>>>> Product Ninja & Advocate at Restlet <http://restlet.com>
>>>>>
>>>>> Blog: http://glaforge.appspot.com/
>>>>> Social: @glaforge <http://twitter.com/glaforge> / Google+
>>>>> <https://plus.google.com/u/0/114130972232398734985/posts>
>>>>>
>>>>>
>>>>
>>>
>>>
>>> --
>>> Guillaume Laforge
>>> Apache Groovy committer & PMC Vice-President
>>> Product Ninja & Advocate at Restlet <http://restlet.com>
>>>
>>> Blog: http://glaforge.appspot.com/
>>> Social: @glaforge <http://twitter.com/glaforge> / Google+
>>> <https://plus.google.com/u/0/114130972232398734985/posts>
>>>
>>
>>
>

Re: Methods for Creating Ranges

Posted by Gerald Wiltse <je...@gmail.com>.
Also, thank you so very much for the response!

Gerald R. Wiltse
jerrywiltse@gmail.com


On Wed, Apr 20, 2016 at 1:57 AM, Gerald Wiltse <je...@gmail.com>
wrote:

> Wow, i just wrote that exact code basically... and started responding to
> your email, but there were various drawbacks to this approach as I don't
> want to have to define handling of every property by name...  Then... it
> hit me...
>
> def v = '1..10'
> assert new GroovyShell().parse(v).run() == [1,2,3,4,5]
>
> It works!!!
>
> Something about the Eval works just a little bit differently than
> GroovyShell i guess.  Perhaps Dierk  can explain.
>
> Last question, how expensive is this invocation of groovyshell and parse
> and all that (resources wise)?  So-so?
>
>
> Gerald R. Wiltse
> jerrywiltse@gmail.com
>
>
> On Wed, Apr 20, 2016 at 1:48 AM, Guillaume Laforge <gl...@gmail.com>
> wrote:
>
>> If you know it's a range when parsing that string, you can do this, with
>> the toInteger() method:
>>
>>    def rangeString = "123..455"
>>    def (String min, String max) = rangeString.tokenize("..")
>>    def range = min.toInteger()..max.toInteger()
>>
>> On Wed, Apr 20, 2016 at 7:26 AM, Gerald Wiltse <je...@gmail.com>
>> wrote:
>>
>>> I don't see how that works in my case, maybe i'm missing something.
>>>
>>> I will clarify:
>>>
>>> I define a variable in web to represent the range:   14502..14520
>>>
>>> The web converts this to a string, and passes it into my code.
>>>
>>> My code then has to receive this string, and then construct a list from
>>> it.
>>>
>>> I could do:
>>>
>>> String rangeString = passedInVar
>>> (String min, String max) = rangeString.tokenize("..")
>>> Range range = min..max
>>>
>>> But i was hoping for a universal "caster" loop which can detect and cast
>>> the common types from strings:
>>> Integers, lists, ranges, maps, booleans..
>>>
>>> 12345
>>> ["this", "is", "Sample", "List"]
>>> 14502..14520
>>> ["key":"value","for":"maps"]
>>> true
>>>
>>> I think eval works for all but ranges.
>>>
>>>
>>>
>>>
>>>
>>>
>>> Gerald R. Wiltse
>>> jerrywiltse@gmail.com
>>>
>>>
>>> On Wed, Apr 20, 2016 at 1:15 AM, Guillaume Laforge <gl...@gmail.com>
>>> wrote:
>>>
>>>> Hi,
>>>>
>>>> You can just replace the bounds with variables.
>>>>
>>>> def a = 1
>>>> def b = 10
>>>> def r = a..b
>>>>
>>>> Isn't that what you're looking for?
>>>>
>>>> Guillaume
>>>>
>>>>
>>>> Le mercredi 20 avril 2016, Gerald Wiltse <je...@gmail.com> a
>>>> écrit :
>>>>
>>>>> I can find no examples of different ways to create a range.  There's a
>>>>> plethora of examples on what you can do when you start by creating a range
>>>>> like so:  "1..10"
>>>>>
>>>>> But, how does one create a range when the min and max values are
>>>>> stored in variables?  There's no range constructor.  I see that it's a form
>>>>> of a list, but I see no helper methods for dynamically creating ranges
>>>>> given a min and max value.
>>>>>
>>>>> I even tried to get really fancy, but this evaluates to a string.
>>>>>
>>>>> def v = "10..15"
>>>>> assert Eval.x(v, "return x")​.getClass()​.name ==
>>>>> "​​​​​​​​​​​java.lang.String"​
>>>>>
>>>>> My use case is this.  I populate a bunch of form fields with variable
>>>>> definitions... but they all get passed to my code as strings. But I want to
>>>>> pass port ranges and lists and maps. So, the Eval() method is exactly what
>>>>> I needed.. it just isn't working for ranges.
>>>>>
>>>>> Regards,
>>>>> Jerry
>>>>>
>>>>>
>>>>> Gerald R. Wiltse
>>>>> jerrywiltse@gmail.com
>>>>>
>>>>>
>>>>
>>>> --
>>>> Guillaume Laforge
>>>> Apache Groovy committer & PMC Vice-President
>>>> Product Ninja & Advocate at Restlet <http://restlet.com>
>>>>
>>>> Blog: http://glaforge.appspot.com/
>>>> Social: @glaforge <http://twitter.com/glaforge> / Google+
>>>> <https://plus.google.com/u/0/114130972232398734985/posts>
>>>>
>>>>
>>>
>>
>>
>> --
>> Guillaume Laforge
>> Apache Groovy committer & PMC Vice-President
>> Product Ninja & Advocate at Restlet <http://restlet.com>
>>
>> Blog: http://glaforge.appspot.com/
>> Social: @glaforge <http://twitter.com/glaforge> / Google+
>> <https://plus.google.com/u/0/114130972232398734985/posts>
>>
>
>

Re: Methods for Creating Ranges

Posted by Gerald Wiltse <je...@gmail.com>.
Indeed it is powerful.  This is for an integration for monitoring and
management platform designed expressly for this purpose. You can already
enter that code into a form field which lets you enter any arbitrary
script. THis is just for a form field which is for properties.

Gerald R. Wiltse
jerrywiltse@gmail.com


On Wed, Apr 20, 2016 at 4:13 AM, Alessio Stalla <al...@gmail.com>
wrote:

> If those strings come from the outside, then using eval on them is a
> no-no. Consider what happens if your input string is "${System.exit(1)}" or
> "${Shell.run('rm -rf /')}". Only use eval on sanitized input and only if
> there is no simpler way.
>
> On 20 April 2016 at 09:32, Guillaume Laforge <gl...@gmail.com> wrote:
>
>> Eval.x(v) should just work as well.
>>
>> Regarding resources / performance, it means spinning the parser and
>> compiler, so it's not for free. Doing your own string parsing logic might
>> be more efficient.
>> Depends on how frequently you have to do that.
>> Le 20 avr. 2016 07:57, "Gerald Wiltse" <je...@gmail.com> a écrit :
>>
>>> Wow, i just wrote that exact code basically... and started responding to
>>> your email, but there were various drawbacks to this approach as I don't
>>> want to have to define handling of every property by name...  Then... it
>>> hit me...
>>>
>>> def v = '1..10'
>>> assert new GroovyShell().parse(v).run() == [1,2,3,4,5]
>>>
>>> It works!!!
>>>
>>> Something about the Eval works just a little bit differently than
>>> GroovyShell i guess.  Perhaps Dierk  can explain.
>>>
>>> Last question, how expensive is this invocation of groovyshell and parse
>>> and all that (resources wise)?  So-so?
>>>
>>>
>>> Gerald R. Wiltse
>>> jerrywiltse@gmail.com
>>>
>>>
>>> On Wed, Apr 20, 2016 at 1:48 AM, Guillaume Laforge <gl...@gmail.com>
>>> wrote:
>>>
>>>> If you know it's a range when parsing that string, you can do this,
>>>> with the toInteger() method:
>>>>
>>>>    def rangeString = "123..455"
>>>>    def (String min, String max) = rangeString.tokenize("..")
>>>>    def range = min.toInteger()..max.toInteger()
>>>>
>>>> On Wed, Apr 20, 2016 at 7:26 AM, Gerald Wiltse <je...@gmail.com>
>>>> wrote:
>>>>
>>>>> I don't see how that works in my case, maybe i'm missing something.
>>>>>
>>>>> I will clarify:
>>>>>
>>>>> I define a variable in web to represent the range:   14502..14520
>>>>>
>>>>> The web converts this to a string, and passes it into my code.
>>>>>
>>>>> My code then has to receive this string, and then construct a list
>>>>> from it.
>>>>>
>>>>> I could do:
>>>>>
>>>>> String rangeString = passedInVar
>>>>> (String min, String max) = rangeString.tokenize("..")
>>>>> Range range = min..max
>>>>>
>>>>> But i was hoping for a universal "caster" loop which can detect and
>>>>> cast the common types from strings:
>>>>> Integers, lists, ranges, maps, booleans..
>>>>>
>>>>> 12345
>>>>> ["this", "is", "Sample", "List"]
>>>>> 14502..14520
>>>>> ["key":"value","for":"maps"]
>>>>> true
>>>>>
>>>>> I think eval works for all but ranges.
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> Gerald R. Wiltse
>>>>> jerrywiltse@gmail.com
>>>>>
>>>>>
>>>>> On Wed, Apr 20, 2016 at 1:15 AM, Guillaume Laforge <glaforge@gmail.com
>>>>> > wrote:
>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> You can just replace the bounds with variables.
>>>>>>
>>>>>> def a = 1
>>>>>> def b = 10
>>>>>> def r = a..b
>>>>>>
>>>>>> Isn't that what you're looking for?
>>>>>>
>>>>>> Guillaume
>>>>>>
>>>>>>
>>>>>> Le mercredi 20 avril 2016, Gerald Wiltse <je...@gmail.com> a
>>>>>> écrit :
>>>>>>
>>>>>>> I can find no examples of different ways to create a range.  There's
>>>>>>> a plethora of examples on what you can do when you start by creating a
>>>>>>> range like so:  "1..10"
>>>>>>>
>>>>>>> But, how does one create a range when the min and max values are
>>>>>>> stored in variables?  There's no range constructor.  I see that it's a form
>>>>>>> of a list, but I see no helper methods for dynamically creating ranges
>>>>>>> given a min and max value.
>>>>>>>
>>>>>>> I even tried to get really fancy, but this evaluates to a string.
>>>>>>>
>>>>>>> def v = "10..15"
>>>>>>> assert Eval.x(v, "return x")​.getClass()​.name ==
>>>>>>> "​​​​​​​​​​​java.lang.String"​
>>>>>>>
>>>>>>> My use case is this.  I populate a bunch of form fields with
>>>>>>> variable definitions... but they all get passed to my code as strings. But
>>>>>>> I want to pass port ranges and lists and maps. So, the Eval() method is
>>>>>>> exactly what I needed.. it just isn't working for ranges.
>>>>>>>
>>>>>>> Regards,
>>>>>>> Jerry
>>>>>>>
>>>>>>>
>>>>>>> Gerald R. Wiltse
>>>>>>> jerrywiltse@gmail.com
>>>>>>>
>>>>>>>
>>>>>>
>>>>>> --
>>>>>> Guillaume Laforge
>>>>>> Apache Groovy committer & PMC Vice-President
>>>>>> Product Ninja & Advocate at Restlet <http://restlet.com>
>>>>>>
>>>>>> Blog: http://glaforge.appspot.com/
>>>>>> Social: @glaforge <http://twitter.com/glaforge> / Google+
>>>>>> <https://plus.google.com/u/0/114130972232398734985/posts>
>>>>>>
>>>>>>
>>>>>
>>>>
>>>>
>>>> --
>>>> Guillaume Laforge
>>>> Apache Groovy committer & PMC Vice-President
>>>> Product Ninja & Advocate at Restlet <http://restlet.com>
>>>>
>>>> Blog: http://glaforge.appspot.com/
>>>> Social: @glaforge <http://twitter.com/glaforge> / Google+
>>>> <https://plus.google.com/u/0/114130972232398734985/posts>
>>>>
>>>
>>>
>

Re: Methods for Creating Ranges

Posted by Alessio Stalla <al...@gmail.com>.
If those strings come from the outside, then using eval on them is a no-no.
Consider what happens if your input string is "${System.exit(1)}" or
"${Shell.run('rm -rf /')}". Only use eval on sanitized input and only if
there is no simpler way.

On 20 April 2016 at 09:32, Guillaume Laforge <gl...@gmail.com> wrote:

> Eval.x(v) should just work as well.
>
> Regarding resources / performance, it means spinning the parser and
> compiler, so it's not for free. Doing your own string parsing logic might
> be more efficient.
> Depends on how frequently you have to do that.
> Le 20 avr. 2016 07:57, "Gerald Wiltse" <je...@gmail.com> a écrit :
>
>> Wow, i just wrote that exact code basically... and started responding to
>> your email, but there were various drawbacks to this approach as I don't
>> want to have to define handling of every property by name...  Then... it
>> hit me...
>>
>> def v = '1..10'
>> assert new GroovyShell().parse(v).run() == [1,2,3,4,5]
>>
>> It works!!!
>>
>> Something about the Eval works just a little bit differently than
>> GroovyShell i guess.  Perhaps Dierk  can explain.
>>
>> Last question, how expensive is this invocation of groovyshell and parse
>> and all that (resources wise)?  So-so?
>>
>>
>> Gerald R. Wiltse
>> jerrywiltse@gmail.com
>>
>>
>> On Wed, Apr 20, 2016 at 1:48 AM, Guillaume Laforge <gl...@gmail.com>
>> wrote:
>>
>>> If you know it's a range when parsing that string, you can do this, with
>>> the toInteger() method:
>>>
>>>    def rangeString = "123..455"
>>>    def (String min, String max) = rangeString.tokenize("..")
>>>    def range = min.toInteger()..max.toInteger()
>>>
>>> On Wed, Apr 20, 2016 at 7:26 AM, Gerald Wiltse <je...@gmail.com>
>>> wrote:
>>>
>>>> I don't see how that works in my case, maybe i'm missing something.
>>>>
>>>> I will clarify:
>>>>
>>>> I define a variable in web to represent the range:   14502..14520
>>>>
>>>> The web converts this to a string, and passes it into my code.
>>>>
>>>> My code then has to receive this string, and then construct a list from
>>>> it.
>>>>
>>>> I could do:
>>>>
>>>> String rangeString = passedInVar
>>>> (String min, String max) = rangeString.tokenize("..")
>>>> Range range = min..max
>>>>
>>>> But i was hoping for a universal "caster" loop which can detect and
>>>> cast the common types from strings:
>>>> Integers, lists, ranges, maps, booleans..
>>>>
>>>> 12345
>>>> ["this", "is", "Sample", "List"]
>>>> 14502..14520
>>>> ["key":"value","for":"maps"]
>>>> true
>>>>
>>>> I think eval works for all but ranges.
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> Gerald R. Wiltse
>>>> jerrywiltse@gmail.com
>>>>
>>>>
>>>> On Wed, Apr 20, 2016 at 1:15 AM, Guillaume Laforge <gl...@gmail.com>
>>>> wrote:
>>>>
>>>>> Hi,
>>>>>
>>>>> You can just replace the bounds with variables.
>>>>>
>>>>> def a = 1
>>>>> def b = 10
>>>>> def r = a..b
>>>>>
>>>>> Isn't that what you're looking for?
>>>>>
>>>>> Guillaume
>>>>>
>>>>>
>>>>> Le mercredi 20 avril 2016, Gerald Wiltse <je...@gmail.com> a
>>>>> écrit :
>>>>>
>>>>>> I can find no examples of different ways to create a range.  There's
>>>>>> a plethora of examples on what you can do when you start by creating a
>>>>>> range like so:  "1..10"
>>>>>>
>>>>>> But, how does one create a range when the min and max values are
>>>>>> stored in variables?  There's no range constructor.  I see that it's a form
>>>>>> of a list, but I see no helper methods for dynamically creating ranges
>>>>>> given a min and max value.
>>>>>>
>>>>>> I even tried to get really fancy, but this evaluates to a string.
>>>>>>
>>>>>> def v = "10..15"
>>>>>> assert Eval.x(v, "return x")​.getClass()​.name ==
>>>>>> "​​​​​​​​​​​java.lang.String"​
>>>>>>
>>>>>> My use case is this.  I populate a bunch of form fields with variable
>>>>>> definitions... but they all get passed to my code as strings. But I want to
>>>>>> pass port ranges and lists and maps. So, the Eval() method is exactly what
>>>>>> I needed.. it just isn't working for ranges.
>>>>>>
>>>>>> Regards,
>>>>>> Jerry
>>>>>>
>>>>>>
>>>>>> Gerald R. Wiltse
>>>>>> jerrywiltse@gmail.com
>>>>>>
>>>>>>
>>>>>
>>>>> --
>>>>> Guillaume Laforge
>>>>> Apache Groovy committer & PMC Vice-President
>>>>> Product Ninja & Advocate at Restlet <http://restlet.com>
>>>>>
>>>>> Blog: http://glaforge.appspot.com/
>>>>> Social: @glaforge <http://twitter.com/glaforge> / Google+
>>>>> <https://plus.google.com/u/0/114130972232398734985/posts>
>>>>>
>>>>>
>>>>
>>>
>>>
>>> --
>>> Guillaume Laforge
>>> Apache Groovy committer & PMC Vice-President
>>> Product Ninja & Advocate at Restlet <http://restlet.com>
>>>
>>> Blog: http://glaforge.appspot.com/
>>> Social: @glaforge <http://twitter.com/glaforge> / Google+
>>> <https://plus.google.com/u/0/114130972232398734985/posts>
>>>
>>
>>

Re: Methods for Creating Ranges

Posted by Felix Dorner <fe...@gmail.com>.

On 20-Apr-16 15:35, Gerald Wiltse wrote:
> I re-arranged it as follows.  Does this seem preferable from a 
> performance perspective?.There will be about an 8:1 ratio... (8 
> matches of this[tmpKey] = v to every 1 exception which hits the catch 
> which needs to be parsed.
>
>                 try {
>                     this[tmpKey] = v
>                 } catch (GroovyCastException e) {
>                     this[tmpKey] = new GroovyShell().parse(v).run()
>                 }
>
It looks tempting, but someone reading this code in 3 years will be 
like: WTF?!? Did you read Bloch: Effective Java? It has a chapter on 
Exceptions and how you should NOT use them. I'd guess this code of yours 
would be a good example for that chapter. When you say you have a form 
input for properties, you imply that NOT every valid groovy expression 
is a valid input.. Then why not just work off all the possible cases?

Felix


Re: Methods for Creating Ranges

Posted by Gerald Wiltse <je...@gmail.com>.
I re-arranged it as follows.  Does this seem preferable from a performance
perspective?.There will be about an 8:1 ratio... (8 matches of this[tmpKey]
= v to every 1 exception which hits the catch which needs to be parsed.

                try {
                    this[tmpKey] = v
                } catch (GroovyCastException e) {
                    this[tmpKey] = new GroovyShell().parse(v).run()
                }

Gerald R. Wiltse
jerrywiltse@gmail.com


On Wed, Apr 20, 2016 at 9:26 AM, Gerald Wiltse <je...@gmail.com>
wrote:

> The code will be executed about once every 10 seconds at a maximum, so the
> load is not extremely high.
>
> Gerald R. Wiltse
> jerrywiltse@gmail.com
>
>
> On Wed, Apr 20, 2016 at 3:32 AM, Guillaume Laforge <gl...@gmail.com>
> wrote:
>
>> Eval.x(v) should just work as well.
>>
>> Regarding resources / performance, it means spinning the parser and
>> compiler, so it's not for free. Doing your own string parsing logic might
>> be more efficient.
>> Depends on how frequently you have to do that.
>> Le 20 avr. 2016 07:57, "Gerald Wiltse" <je...@gmail.com> a écrit :
>>
>>> Wow, i just wrote that exact code basically... and started responding to
>>> your email, but there were various drawbacks to this approach as I don't
>>> want to have to define handling of every property by name...  Then... it
>>> hit me...
>>>
>>> def v = '1..10'
>>> assert new GroovyShell().parse(v).run() == [1,2,3,4,5]
>>>
>>> It works!!!
>>>
>>> Something about the Eval works just a little bit differently than
>>> GroovyShell i guess.  Perhaps Dierk  can explain.
>>>
>>> Last question, how expensive is this invocation of groovyshell and parse
>>> and all that (resources wise)?  So-so?
>>>
>>>
>>> Gerald R. Wiltse
>>> jerrywiltse@gmail.com
>>>
>>>
>>> On Wed, Apr 20, 2016 at 1:48 AM, Guillaume Laforge <gl...@gmail.com>
>>> wrote:
>>>
>>>> If you know it's a range when parsing that string, you can do this,
>>>> with the toInteger() method:
>>>>
>>>>    def rangeString = "123..455"
>>>>    def (String min, String max) = rangeString.tokenize("..")
>>>>    def range = min.toInteger()..max.toInteger()
>>>>
>>>> On Wed, Apr 20, 2016 at 7:26 AM, Gerald Wiltse <je...@gmail.com>
>>>> wrote:
>>>>
>>>>> I don't see how that works in my case, maybe i'm missing something.
>>>>>
>>>>> I will clarify:
>>>>>
>>>>> I define a variable in web to represent the range:   14502..14520
>>>>>
>>>>> The web converts this to a string, and passes it into my code.
>>>>>
>>>>> My code then has to receive this string, and then construct a list
>>>>> from it.
>>>>>
>>>>> I could do:
>>>>>
>>>>> String rangeString = passedInVar
>>>>> (String min, String max) = rangeString.tokenize("..")
>>>>> Range range = min..max
>>>>>
>>>>> But i was hoping for a universal "caster" loop which can detect and
>>>>> cast the common types from strings:
>>>>> Integers, lists, ranges, maps, booleans..
>>>>>
>>>>> 12345
>>>>> ["this", "is", "Sample", "List"]
>>>>> 14502..14520
>>>>> ["key":"value","for":"maps"]
>>>>> true
>>>>>
>>>>> I think eval works for all but ranges.
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> Gerald R. Wiltse
>>>>> jerrywiltse@gmail.com
>>>>>
>>>>>
>>>>> On Wed, Apr 20, 2016 at 1:15 AM, Guillaume Laforge <glaforge@gmail.com
>>>>> > wrote:
>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> You can just replace the bounds with variables.
>>>>>>
>>>>>> def a = 1
>>>>>> def b = 10
>>>>>> def r = a..b
>>>>>>
>>>>>> Isn't that what you're looking for?
>>>>>>
>>>>>> Guillaume
>>>>>>
>>>>>>
>>>>>> Le mercredi 20 avril 2016, Gerald Wiltse <je...@gmail.com> a
>>>>>> écrit :
>>>>>>
>>>>>>> I can find no examples of different ways to create a range.  There's
>>>>>>> a plethora of examples on what you can do when you start by creating a
>>>>>>> range like so:  "1..10"
>>>>>>>
>>>>>>> But, how does one create a range when the min and max values are
>>>>>>> stored in variables?  There's no range constructor.  I see that it's a form
>>>>>>> of a list, but I see no helper methods for dynamically creating ranges
>>>>>>> given a min and max value.
>>>>>>>
>>>>>>> I even tried to get really fancy, but this evaluates to a string.
>>>>>>>
>>>>>>> def v = "10..15"
>>>>>>> assert Eval.x(v, "return x")​.getClass()​.name ==
>>>>>>> "​​​​​​​​​​​java.lang.String"​
>>>>>>>
>>>>>>> My use case is this.  I populate a bunch of form fields with
>>>>>>> variable definitions... but they all get passed to my code as strings. But
>>>>>>> I want to pass port ranges and lists and maps. So, the Eval() method is
>>>>>>> exactly what I needed.. it just isn't working for ranges.
>>>>>>>
>>>>>>> Regards,
>>>>>>> Jerry
>>>>>>>
>>>>>>>
>>>>>>> Gerald R. Wiltse
>>>>>>> jerrywiltse@gmail.com
>>>>>>>
>>>>>>>
>>>>>>
>>>>>> --
>>>>>> Guillaume Laforge
>>>>>> Apache Groovy committer & PMC Vice-President
>>>>>> Product Ninja & Advocate at Restlet <http://restlet.com>
>>>>>>
>>>>>> Blog: http://glaforge.appspot.com/
>>>>>> Social: @glaforge <http://twitter.com/glaforge> / Google+
>>>>>> <https://plus.google.com/u/0/114130972232398734985/posts>
>>>>>>
>>>>>>
>>>>>
>>>>
>>>>
>>>> --
>>>> Guillaume Laforge
>>>> Apache Groovy committer & PMC Vice-President
>>>> Product Ninja & Advocate at Restlet <http://restlet.com>
>>>>
>>>> Blog: http://glaforge.appspot.com/
>>>> Social: @glaforge <http://twitter.com/glaforge> / Google+
>>>> <https://plus.google.com/u/0/114130972232398734985/posts>
>>>>
>>>
>>>
>

Re: Methods for Creating Ranges

Posted by Gerald Wiltse <je...@gmail.com>.
The code will be executed about once every 10 seconds at a maximum, so the
load is not extremely high.

Gerald R. Wiltse
jerrywiltse@gmail.com


On Wed, Apr 20, 2016 at 3:32 AM, Guillaume Laforge <gl...@gmail.com>
wrote:

> Eval.x(v) should just work as well.
>
> Regarding resources / performance, it means spinning the parser and
> compiler, so it's not for free. Doing your own string parsing logic might
> be more efficient.
> Depends on how frequently you have to do that.
> Le 20 avr. 2016 07:57, "Gerald Wiltse" <je...@gmail.com> a écrit :
>
>> Wow, i just wrote that exact code basically... and started responding to
>> your email, but there were various drawbacks to this approach as I don't
>> want to have to define handling of every property by name...  Then... it
>> hit me...
>>
>> def v = '1..10'
>> assert new GroovyShell().parse(v).run() == [1,2,3,4,5]
>>
>> It works!!!
>>
>> Something about the Eval works just a little bit differently than
>> GroovyShell i guess.  Perhaps Dierk  can explain.
>>
>> Last question, how expensive is this invocation of groovyshell and parse
>> and all that (resources wise)?  So-so?
>>
>>
>> Gerald R. Wiltse
>> jerrywiltse@gmail.com
>>
>>
>> On Wed, Apr 20, 2016 at 1:48 AM, Guillaume Laforge <gl...@gmail.com>
>> wrote:
>>
>>> If you know it's a range when parsing that string, you can do this, with
>>> the toInteger() method:
>>>
>>>    def rangeString = "123..455"
>>>    def (String min, String max) = rangeString.tokenize("..")
>>>    def range = min.toInteger()..max.toInteger()
>>>
>>> On Wed, Apr 20, 2016 at 7:26 AM, Gerald Wiltse <je...@gmail.com>
>>> wrote:
>>>
>>>> I don't see how that works in my case, maybe i'm missing something.
>>>>
>>>> I will clarify:
>>>>
>>>> I define a variable in web to represent the range:   14502..14520
>>>>
>>>> The web converts this to a string, and passes it into my code.
>>>>
>>>> My code then has to receive this string, and then construct a list from
>>>> it.
>>>>
>>>> I could do:
>>>>
>>>> String rangeString = passedInVar
>>>> (String min, String max) = rangeString.tokenize("..")
>>>> Range range = min..max
>>>>
>>>> But i was hoping for a universal "caster" loop which can detect and
>>>> cast the common types from strings:
>>>> Integers, lists, ranges, maps, booleans..
>>>>
>>>> 12345
>>>> ["this", "is", "Sample", "List"]
>>>> 14502..14520
>>>> ["key":"value","for":"maps"]
>>>> true
>>>>
>>>> I think eval works for all but ranges.
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> Gerald R. Wiltse
>>>> jerrywiltse@gmail.com
>>>>
>>>>
>>>> On Wed, Apr 20, 2016 at 1:15 AM, Guillaume Laforge <gl...@gmail.com>
>>>> wrote:
>>>>
>>>>> Hi,
>>>>>
>>>>> You can just replace the bounds with variables.
>>>>>
>>>>> def a = 1
>>>>> def b = 10
>>>>> def r = a..b
>>>>>
>>>>> Isn't that what you're looking for?
>>>>>
>>>>> Guillaume
>>>>>
>>>>>
>>>>> Le mercredi 20 avril 2016, Gerald Wiltse <je...@gmail.com> a
>>>>> écrit :
>>>>>
>>>>>> I can find no examples of different ways to create a range.  There's
>>>>>> a plethora of examples on what you can do when you start by creating a
>>>>>> range like so:  "1..10"
>>>>>>
>>>>>> But, how does one create a range when the min and max values are
>>>>>> stored in variables?  There's no range constructor.  I see that it's a form
>>>>>> of a list, but I see no helper methods for dynamically creating ranges
>>>>>> given a min and max value.
>>>>>>
>>>>>> I even tried to get really fancy, but this evaluates to a string.
>>>>>>
>>>>>> def v = "10..15"
>>>>>> assert Eval.x(v, "return x")​.getClass()​.name ==
>>>>>> "​​​​​​​​​​​java.lang.String"​
>>>>>>
>>>>>> My use case is this.  I populate a bunch of form fields with variable
>>>>>> definitions... but they all get passed to my code as strings. But I want to
>>>>>> pass port ranges and lists and maps. So, the Eval() method is exactly what
>>>>>> I needed.. it just isn't working for ranges.
>>>>>>
>>>>>> Regards,
>>>>>> Jerry
>>>>>>
>>>>>>
>>>>>> Gerald R. Wiltse
>>>>>> jerrywiltse@gmail.com
>>>>>>
>>>>>>
>>>>>
>>>>> --
>>>>> Guillaume Laforge
>>>>> Apache Groovy committer & PMC Vice-President
>>>>> Product Ninja & Advocate at Restlet <http://restlet.com>
>>>>>
>>>>> Blog: http://glaforge.appspot.com/
>>>>> Social: @glaforge <http://twitter.com/glaforge> / Google+
>>>>> <https://plus.google.com/u/0/114130972232398734985/posts>
>>>>>
>>>>>
>>>>
>>>
>>>
>>> --
>>> Guillaume Laforge
>>> Apache Groovy committer & PMC Vice-President
>>> Product Ninja & Advocate at Restlet <http://restlet.com>
>>>
>>> Blog: http://glaforge.appspot.com/
>>> Social: @glaforge <http://twitter.com/glaforge> / Google+
>>> <https://plus.google.com/u/0/114130972232398734985/posts>
>>>
>>
>>

Re: Methods for Creating Ranges

Posted by Guillaume Laforge <gl...@gmail.com>.
Eval.x(v) should just work as well.

Regarding resources / performance, it means spinning the parser and
compiler, so it's not for free. Doing your own string parsing logic might
be more efficient.
Depends on how frequently you have to do that.
Le 20 avr. 2016 07:57, "Gerald Wiltse" <je...@gmail.com> a écrit :

> Wow, i just wrote that exact code basically... and started responding to
> your email, but there were various drawbacks to this approach as I don't
> want to have to define handling of every property by name...  Then... it
> hit me...
>
> def v = '1..10'
> assert new GroovyShell().parse(v).run() == [1,2,3,4,5]
>
> It works!!!
>
> Something about the Eval works just a little bit differently than
> GroovyShell i guess.  Perhaps Dierk  can explain.
>
> Last question, how expensive is this invocation of groovyshell and parse
> and all that (resources wise)?  So-so?
>
>
> Gerald R. Wiltse
> jerrywiltse@gmail.com
>
>
> On Wed, Apr 20, 2016 at 1:48 AM, Guillaume Laforge <gl...@gmail.com>
> wrote:
>
>> If you know it's a range when parsing that string, you can do this, with
>> the toInteger() method:
>>
>>    def rangeString = "123..455"
>>    def (String min, String max) = rangeString.tokenize("..")
>>    def range = min.toInteger()..max.toInteger()
>>
>> On Wed, Apr 20, 2016 at 7:26 AM, Gerald Wiltse <je...@gmail.com>
>> wrote:
>>
>>> I don't see how that works in my case, maybe i'm missing something.
>>>
>>> I will clarify:
>>>
>>> I define a variable in web to represent the range:   14502..14520
>>>
>>> The web converts this to a string, and passes it into my code.
>>>
>>> My code then has to receive this string, and then construct a list from
>>> it.
>>>
>>> I could do:
>>>
>>> String rangeString = passedInVar
>>> (String min, String max) = rangeString.tokenize("..")
>>> Range range = min..max
>>>
>>> But i was hoping for a universal "caster" loop which can detect and cast
>>> the common types from strings:
>>> Integers, lists, ranges, maps, booleans..
>>>
>>> 12345
>>> ["this", "is", "Sample", "List"]
>>> 14502..14520
>>> ["key":"value","for":"maps"]
>>> true
>>>
>>> I think eval works for all but ranges.
>>>
>>>
>>>
>>>
>>>
>>>
>>> Gerald R. Wiltse
>>> jerrywiltse@gmail.com
>>>
>>>
>>> On Wed, Apr 20, 2016 at 1:15 AM, Guillaume Laforge <gl...@gmail.com>
>>> wrote:
>>>
>>>> Hi,
>>>>
>>>> You can just replace the bounds with variables.
>>>>
>>>> def a = 1
>>>> def b = 10
>>>> def r = a..b
>>>>
>>>> Isn't that what you're looking for?
>>>>
>>>> Guillaume
>>>>
>>>>
>>>> Le mercredi 20 avril 2016, Gerald Wiltse <je...@gmail.com> a
>>>> écrit :
>>>>
>>>>> I can find no examples of different ways to create a range.  There's a
>>>>> plethora of examples on what you can do when you start by creating a range
>>>>> like so:  "1..10"
>>>>>
>>>>> But, how does one create a range when the min and max values are
>>>>> stored in variables?  There's no range constructor.  I see that it's a form
>>>>> of a list, but I see no helper methods for dynamically creating ranges
>>>>> given a min and max value.
>>>>>
>>>>> I even tried to get really fancy, but this evaluates to a string.
>>>>>
>>>>> def v = "10..15"
>>>>> assert Eval.x(v, "return x")​.getClass()​.name ==
>>>>> "​​​​​​​​​​​java.lang.String"​
>>>>>
>>>>> My use case is this.  I populate a bunch of form fields with variable
>>>>> definitions... but they all get passed to my code as strings. But I want to
>>>>> pass port ranges and lists and maps. So, the Eval() method is exactly what
>>>>> I needed.. it just isn't working for ranges.
>>>>>
>>>>> Regards,
>>>>> Jerry
>>>>>
>>>>>
>>>>> Gerald R. Wiltse
>>>>> jerrywiltse@gmail.com
>>>>>
>>>>>
>>>>
>>>> --
>>>> Guillaume Laforge
>>>> Apache Groovy committer & PMC Vice-President
>>>> Product Ninja & Advocate at Restlet <http://restlet.com>
>>>>
>>>> Blog: http://glaforge.appspot.com/
>>>> Social: @glaforge <http://twitter.com/glaforge> / Google+
>>>> <https://plus.google.com/u/0/114130972232398734985/posts>
>>>>
>>>>
>>>
>>
>>
>> --
>> Guillaume Laforge
>> Apache Groovy committer & PMC Vice-President
>> Product Ninja & Advocate at Restlet <http://restlet.com>
>>
>> Blog: http://glaforge.appspot.com/
>> Social: @glaforge <http://twitter.com/glaforge> / Google+
>> <https://plus.google.com/u/0/114130972232398734985/posts>
>>
>
>

Re: Methods for Creating Ranges

Posted by Gerald Wiltse <je...@gmail.com>.
Wow, i just wrote that exact code basically... and started responding to
your email, but there were various drawbacks to this approach as I don't
want to have to define handling of every property by name...  Then... it
hit me...

def v = '1..10'
assert new GroovyShell().parse(v).run() == [1,2,3,4,5]

It works!!!

Something about the Eval works just a little bit differently than
GroovyShell i guess.  Perhaps Dierk  can explain.

Last question, how expensive is this invocation of groovyshell and parse
and all that (resources wise)?  So-so?


Gerald R. Wiltse
jerrywiltse@gmail.com


On Wed, Apr 20, 2016 at 1:48 AM, Guillaume Laforge <gl...@gmail.com>
wrote:

> If you know it's a range when parsing that string, you can do this, with
> the toInteger() method:
>
>    def rangeString = "123..455"
>    def (String min, String max) = rangeString.tokenize("..")
>    def range = min.toInteger()..max.toInteger()
>
> On Wed, Apr 20, 2016 at 7:26 AM, Gerald Wiltse <je...@gmail.com>
> wrote:
>
>> I don't see how that works in my case, maybe i'm missing something.
>>
>> I will clarify:
>>
>> I define a variable in web to represent the range:   14502..14520
>>
>> The web converts this to a string, and passes it into my code.
>>
>> My code then has to receive this string, and then construct a list from
>> it.
>>
>> I could do:
>>
>> String rangeString = passedInVar
>> (String min, String max) = rangeString.tokenize("..")
>> Range range = min..max
>>
>> But i was hoping for a universal "caster" loop which can detect and cast
>> the common types from strings:
>> Integers, lists, ranges, maps, booleans..
>>
>> 12345
>> ["this", "is", "Sample", "List"]
>> 14502..14520
>> ["key":"value","for":"maps"]
>> true
>>
>> I think eval works for all but ranges.
>>
>>
>>
>>
>>
>>
>> Gerald R. Wiltse
>> jerrywiltse@gmail.com
>>
>>
>> On Wed, Apr 20, 2016 at 1:15 AM, Guillaume Laforge <gl...@gmail.com>
>> wrote:
>>
>>> Hi,
>>>
>>> You can just replace the bounds with variables.
>>>
>>> def a = 1
>>> def b = 10
>>> def r = a..b
>>>
>>> Isn't that what you're looking for?
>>>
>>> Guillaume
>>>
>>>
>>> Le mercredi 20 avril 2016, Gerald Wiltse <je...@gmail.com> a
>>> écrit :
>>>
>>>> I can find no examples of different ways to create a range.  There's a
>>>> plethora of examples on what you can do when you start by creating a range
>>>> like so:  "1..10"
>>>>
>>>> But, how does one create a range when the min and max values are stored
>>>> in variables?  There's no range constructor.  I see that it's a form of a
>>>> list, but I see no helper methods for dynamically creating ranges given a
>>>> min and max value.
>>>>
>>>> I even tried to get really fancy, but this evaluates to a string.
>>>>
>>>> def v = "10..15"
>>>> assert Eval.x(v, "return x")​.getClass()​.name ==
>>>> "​​​​​​​​​​​java.lang.String"​
>>>>
>>>> My use case is this.  I populate a bunch of form fields with variable
>>>> definitions... but they all get passed to my code as strings. But I want to
>>>> pass port ranges and lists and maps. So, the Eval() method is exactly what
>>>> I needed.. it just isn't working for ranges.
>>>>
>>>> Regards,
>>>> Jerry
>>>>
>>>>
>>>> Gerald R. Wiltse
>>>> jerrywiltse@gmail.com
>>>>
>>>>
>>>
>>> --
>>> Guillaume Laforge
>>> Apache Groovy committer & PMC Vice-President
>>> Product Ninja & Advocate at Restlet <http://restlet.com>
>>>
>>> Blog: http://glaforge.appspot.com/
>>> Social: @glaforge <http://twitter.com/glaforge> / Google+
>>> <https://plus.google.com/u/0/114130972232398734985/posts>
>>>
>>>
>>
>
>
> --
> Guillaume Laforge
> Apache Groovy committer & PMC Vice-President
> Product Ninja & Advocate at Restlet <http://restlet.com>
>
> Blog: http://glaforge.appspot.com/
> Social: @glaforge <http://twitter.com/glaforge> / Google+
> <https://plus.google.com/u/0/114130972232398734985/posts>
>

Re: Methods for Creating Ranges

Posted by Guillaume Laforge <gl...@gmail.com>.
If you know it's a range when parsing that string, you can do this, with
the toInteger() method:

   def rangeString = "123..455"
   def (String min, String max) = rangeString.tokenize("..")
   def range = min.toInteger()..max.toInteger()

On Wed, Apr 20, 2016 at 7:26 AM, Gerald Wiltse <je...@gmail.com>
wrote:

> I don't see how that works in my case, maybe i'm missing something.
>
> I will clarify:
>
> I define a variable in web to represent the range:   14502..14520
>
> The web converts this to a string, and passes it into my code.
>
> My code then has to receive this string, and then construct a list from
> it.
>
> I could do:
>
> String rangeString = passedInVar
> (String min, String max) = rangeString.tokenize("..")
> Range range = min..max
>
> But i was hoping for a universal "caster" loop which can detect and cast
> the common types from strings:
> Integers, lists, ranges, maps, booleans..
>
> 12345
> ["this", "is", "Sample", "List"]
> 14502..14520
> ["key":"value","for":"maps"]
> true
>
> I think eval works for all but ranges.
>
>
>
>
>
>
> Gerald R. Wiltse
> jerrywiltse@gmail.com
>
>
> On Wed, Apr 20, 2016 at 1:15 AM, Guillaume Laforge <gl...@gmail.com>
> wrote:
>
>> Hi,
>>
>> You can just replace the bounds with variables.
>>
>> def a = 1
>> def b = 10
>> def r = a..b
>>
>> Isn't that what you're looking for?
>>
>> Guillaume
>>
>>
>> Le mercredi 20 avril 2016, Gerald Wiltse <je...@gmail.com> a
>> écrit :
>>
>>> I can find no examples of different ways to create a range.  There's a
>>> plethora of examples on what you can do when you start by creating a range
>>> like so:  "1..10"
>>>
>>> But, how does one create a range when the min and max values are stored
>>> in variables?  There's no range constructor.  I see that it's a form of a
>>> list, but I see no helper methods for dynamically creating ranges given a
>>> min and max value.
>>>
>>> I even tried to get really fancy, but this evaluates to a string.
>>>
>>> def v = "10..15"
>>> assert Eval.x(v, "return x")​.getClass()​.name ==
>>> "​​​​​​​​​​​java.lang.String"​
>>>
>>> My use case is this.  I populate a bunch of form fields with variable
>>> definitions... but they all get passed to my code as strings. But I want to
>>> pass port ranges and lists and maps. So, the Eval() method is exactly what
>>> I needed.. it just isn't working for ranges.
>>>
>>> Regards,
>>> Jerry
>>>
>>>
>>> Gerald R. Wiltse
>>> jerrywiltse@gmail.com
>>>
>>>
>>
>> --
>> Guillaume Laforge
>> Apache Groovy committer & PMC Vice-President
>> Product Ninja & Advocate at Restlet <http://restlet.com>
>>
>> Blog: http://glaforge.appspot.com/
>> Social: @glaforge <http://twitter.com/glaforge> / Google+
>> <https://plus.google.com/u/0/114130972232398734985/posts>
>>
>>
>


-- 
Guillaume Laforge
Apache Groovy committer & PMC Vice-President
Product Ninja & Advocate at Restlet <http://restlet.com>

Blog: http://glaforge.appspot.com/
Social: @glaforge <http://twitter.com/glaforge> / Google+
<https://plus.google.com/u/0/114130972232398734985/posts>

Re: Methods for Creating Ranges

Posted by Gerald Wiltse <je...@gmail.com>.
Here is my current loop btw, it just bombs on the range, says its a string.

        taskProps.each { k, v ->
            String tmpKey = k.replaceAll('system.',
'').toLowerCase().replaceAll('\\.','')
            if (this.hasProperty(tmpKey)) {
                this."$tmpKey" =  Eval.x(v, "return x")
            }
        }



Gerald R. Wiltse
jerrywiltse@gmail.com


On Wed, Apr 20, 2016 at 1:26 AM, Gerald Wiltse <je...@gmail.com>
wrote:

> I don't see how that works in my case, maybe i'm missing something.
>
> I will clarify:
>
> I define a variable in web to represent the range:   14502..14520
>
> The web converts this to a string, and passes it into my code.
>
> My code then has to receive this string, and then construct a list from
> it.
>
> I could do:
>
> String rangeString = passedInVar
> (String min, String max) = rangeString.tokenize("..")
> Range range = min..max
>
> But i was hoping for a universal "caster" loop which can detect and cast
> the common types from strings:
> Integers, lists, ranges, maps, booleans..
>
> 12345
> ["this", "is", "Sample", "List"]
> 14502..14520
> ["key":"value","for":"maps"]
> true
>
> I think eval works for all but ranges.
>
>
>
>
>
>
> Gerald R. Wiltse
> jerrywiltse@gmail.com
>
>
> On Wed, Apr 20, 2016 at 1:15 AM, Guillaume Laforge <gl...@gmail.com>
> wrote:
>
>> Hi,
>>
>> You can just replace the bounds with variables.
>>
>> def a = 1
>> def b = 10
>> def r = a..b
>>
>> Isn't that what you're looking for?
>>
>> Guillaume
>>
>>
>> Le mercredi 20 avril 2016, Gerald Wiltse <je...@gmail.com> a
>> écrit :
>>
>>> I can find no examples of different ways to create a range.  There's a
>>> plethora of examples on what you can do when you start by creating a range
>>> like so:  "1..10"
>>>
>>> But, how does one create a range when the min and max values are stored
>>> in variables?  There's no range constructor.  I see that it's a form of a
>>> list, but I see no helper methods for dynamically creating ranges given a
>>> min and max value.
>>>
>>> I even tried to get really fancy, but this evaluates to a string.
>>>
>>> def v = "10..15"
>>> assert Eval.x(v, "return x")​.getClass()​.name ==
>>> "​​​​​​​​​​​java.lang.String"​
>>>
>>> My use case is this.  I populate a bunch of form fields with variable
>>> definitions... but they all get passed to my code as strings. But I want to
>>> pass port ranges and lists and maps. So, the Eval() method is exactly what
>>> I needed.. it just isn't working for ranges.
>>>
>>> Regards,
>>> Jerry
>>>
>>>
>>> Gerald R. Wiltse
>>> jerrywiltse@gmail.com
>>>
>>>
>>
>> --
>> Guillaume Laforge
>> Apache Groovy committer & PMC Vice-President
>> Product Ninja & Advocate at Restlet <http://restlet.com>
>>
>> Blog: http://glaforge.appspot.com/
>> Social: @glaforge <http://twitter.com/glaforge> / Google+
>> <https://plus.google.com/u/0/114130972232398734985/posts>
>>
>>
>

Re: Methods for Creating Ranges

Posted by Gerald Wiltse <je...@gmail.com>.
I don't see how that works in my case, maybe i'm missing something.

I will clarify:

I define a variable in web to represent the range:   14502..14520

The web converts this to a string, and passes it into my code.

My code then has to receive this string, and then construct a list from it.

I could do:

String rangeString = passedInVar
(String min, String max) = rangeString.tokenize("..")
Range range = min..max

But i was hoping for a universal "caster" loop which can detect and cast
the common types from strings:
Integers, lists, ranges, maps, booleans..

12345
["this", "is", "Sample", "List"]
14502..14520
["key":"value","for":"maps"]
true

I think eval works for all but ranges.






Gerald R. Wiltse
jerrywiltse@gmail.com


On Wed, Apr 20, 2016 at 1:15 AM, Guillaume Laforge <gl...@gmail.com>
wrote:

> Hi,
>
> You can just replace the bounds with variables.
>
> def a = 1
> def b = 10
> def r = a..b
>
> Isn't that what you're looking for?
>
> Guillaume
>
>
> Le mercredi 20 avril 2016, Gerald Wiltse <je...@gmail.com> a écrit :
>
>> I can find no examples of different ways to create a range.  There's a
>> plethora of examples on what you can do when you start by creating a range
>> like so:  "1..10"
>>
>> But, how does one create a range when the min and max values are stored
>> in variables?  There's no range constructor.  I see that it's a form of a
>> list, but I see no helper methods for dynamically creating ranges given a
>> min and max value.
>>
>> I even tried to get really fancy, but this evaluates to a string.
>>
>> def v = "10..15"
>> assert Eval.x(v, "return x")​.getClass()​.name ==
>> "​​​​​​​​​​​java.lang.String"​
>>
>> My use case is this.  I populate a bunch of form fields with variable
>> definitions... but they all get passed to my code as strings. But I want to
>> pass port ranges and lists and maps. So, the Eval() method is exactly what
>> I needed.. it just isn't working for ranges.
>>
>> Regards,
>> Jerry
>>
>>
>> Gerald R. Wiltse
>> jerrywiltse@gmail.com
>>
>>
>
> --
> Guillaume Laforge
> Apache Groovy committer & PMC Vice-President
> Product Ninja & Advocate at Restlet <http://restlet.com>
>
> Blog: http://glaforge.appspot.com/
> Social: @glaforge <http://twitter.com/glaforge> / Google+
> <https://plus.google.com/u/0/114130972232398734985/posts>
>
>

Re: Methods for Creating Ranges

Posted by Guillaume Laforge <gl...@gmail.com>.
Hi,

You can just replace the bounds with variables.

def a = 1
def b = 10
def r = a..b

Isn't that what you're looking for?

Guillaume


Le mercredi 20 avril 2016, Gerald Wiltse <je...@gmail.com> a écrit :

> I can find no examples of different ways to create a range.  There's a
> plethora of examples on what you can do when you start by creating a range
> like so:  "1..10"
>
> But, how does one create a range when the min and max values are stored in
> variables?  There's no range constructor.  I see that it's a form of a
> list, but I see no helper methods for dynamically creating ranges given a
> min and max value.
>
> I even tried to get really fancy, but this evaluates to a string.
>
> def v = "10..15"
> assert Eval.x(v, "return x")​.getClass()​.name ==
> "​​​​​​​​​​​java.lang.String"​
>
> My use case is this.  I populate a bunch of form fields with variable
> definitions... but they all get passed to my code as strings. But I want to
> pass port ranges and lists and maps. So, the Eval() method is exactly what
> I needed.. it just isn't working for ranges.
>
> Regards,
> Jerry
>
>
> Gerald R. Wiltse
> jerrywiltse@gmail.com
> <javascript:_e(%7B%7D,'cvml','jerrywiltse@gmail.com');>
>
>

-- 
Guillaume Laforge
Apache Groovy committer & PMC Vice-President
Product Ninja & Advocate at Restlet <http://restlet.com>

Blog: http://glaforge.appspot.com/
Social: @glaforge <http://twitter.com/glaforge> / Google+
<https://plus.google.com/u/0/114130972232398734985/posts>