Groovy DSL using parenthesis? - syntax

I have a groovy DSL script like this:
entity(attribute1:"one", attribute2:"two")
so far so good. I run the script and set the script's delegate to a class where entity's defined, and the class handles everything.
Now I want to do this:
entity(attibute1:(subattribute1:"one", subattribute2:"two"))
Is this somehow syntactically possible? Since (subattribute1:"one", subattribute2:"two") itself doesn't mean anything, I'm assuming not, though I'm wondering if there are some Groovy magic that I'm not aware of that allows this.
And I don't want to do
entity(attibute1:[subattribute1:"one", subattribute2:"two"])
even though I know that works. Just a syntax preference.

No, you have to use the square brace (as you have said you don't want).
The first example:
entity(attribute1:"one", attribute2:"two")
is a shortcut for actually calling:
entity( [ attribute1:"one", attribute2:"two" ] )
So, you would either need the square braces, (to signify the attribute1 key contains a map, or you would need to prefix the brace with another method name such as:
entity(attibute1:attribute(subattribute1:"one", subattribute2:"two"))

Related

What is the syntax for describing how to call a command?

If I have this command:
do_something
And requires 2 arguments argument_1 argument_2
argument_1 can be anything
argument_2 only can be true or false
A non-required third argument can be added argument_3
What is the standard to describe a script calling template?
I remember to have read somewhere about the different meanings of <> and [] and {}. For example:
<> mean required
[] mean non-required
{} contains a list of possible values
So for my example it will be
do_someting <argument_1> {true,false} [argument_3]
But I don't find any place that is confirming this syntax.
I would write the following:
do_someting argument_1 {true|false} [argument_3]
I think mendatory arguments don't need any kind of braces, it looks clearer like that. Furthermore, the pipe feels more standard to represent an "or" statement.
I am not aware of such standard, but you can have a look at Google recommendations or docopt for example. Also, here is a POSIX document which may interest you.

Ruby: how to pass object to a block and return a calculated value depending on the obj?

I would like to do something similar:
seconds=Time.parse("0:26:29.489").magic{|z| z.hour+z.min+z.sec+z.nsec.fdiv(1_000_000)}
to convert a timestamp into seconds (with fractions too), instead of writing:
d=Time.parse("0:26:29.489")
seconds=d.hour+d.min+d.sec+d.nsec.fdiv(1_000_000)
to spare a temporary "d" variable. But what should I use for "magic" if any?
Ruby has tap, but that won't help you here. What you want is something that would be called pipe, but sadly it's not there. At least not without a gem that monkey patches Object. Though I think it should be.
You can create a lambda and immediately call it, which will avoid the intermediate variable (or at least contain it within the lambda's block scope, as in your magic example), but I'm not sure you gain much, and would probably stick with what you have. The lambda approach would look like this:
# will return the value for "seconds"
->(d) { d.hour+d.min+d.sec+d.nsec.fdiv(1_000_000) }.(Time.parse("0:26:29.489"))

what exactly author wants me to understand?

"Inches/yard: #{12*3}"
"#{"Tora! "*3}"
The second example is confusing, unless you remember that everything is an object in
Ruby (yes, even string literals! They are of class String.). Since the string literal
creates a String object, you can act on it just like any other object. In this case,
multiplying a string by 3 simply does what you would think: makes three copies of the
string.
I read the above para in one of the ruby book. The first line says The second example is confusing, unless you remember that everything is an object in Ruby. What is there in the second example that i should remember ,everything is an object in ruby ? Isn't it just a feature that multiplying by 3 will print tora three times ?
I don't exactly understand what does the author want me to understand from the above paragraph
Well, yes you can consider it a feature maybe, but what the author is perhaps trying to explain (although not very clearly at least in this one paragraph), is that what actually is happening is this:
"Tora !" is an object of class String ("everything is an object")
"you can act on it just like any other object", meaning:
"you can call any method on it just like any other object".
In this case you are calling the method * (multiply).
So what ACTUALLY is happening is that the "Tora !" String gets called in a fashion like this:
"Tora ! ".*(3)
=> "Tora ! Tora ! Tora ! "
You see? The operator * is just a method on the String object.
In many simpler languages operators are actually "baked into" the language itself, and do not operate on the targets as method calls.
If you're not used to other languages you might not find it all that remarkable, since in Ruby it's just a normal everyday thing. You just never need to type 1.+(2), Ruby does it for you automatically when you type 1 + 2.
So this is what the author wants you to remember - all operators and operations are just essentially method calls on other objects.
"Tora! a" is an instance of the String class. You can call methods on it. This isn't possible in many languages, e.g. PHP.
('*' is just the method name)
"#{"Tora! "*3}"
"Isn't it just a feature that multiplying by 3 will print tora three times ?".
That is inexact. There is no such thing as a multiplying operator in Ruby. There is a method ".*" (and the parser treats "*" the same way) defined on both String and Numeric objects (but both don't print anything). They do very different things, but the result is what you'd expect.
Well, maybe this was not what the author wanted you to understand, it is important anyway.

Is it possible in Ruby to define a method which name ends with : (colon)?

Just wondering if it is possible, by some loophole, to define a method name that ends in a colon. The purpose it to make things look like this:
mymethod: arg1,arg2,arg3
It is technically possible to define a method with that name, but you can't call it like that because of syntax rules. (The colon is considered a different token.) You would have to do send('mymethod:', args), which defeats the purpose.

test if string can be converted to a number in FreeMarker

I am trying to test whether a string can be converted into a number in FreeMarker. For example, "123" and "3.14" can be converted, but "foo" can't. I know that I can test for this by using the number method on the string (e.g. "123"?number) and seeing whether it produces an error, but I am looking for a way to test for this without causing an error.
I tried ?matches("^\d+$"), and it works fine for integers, but I am looking for something that works on all numbers.
I can probably do it using a more sophisticated regex, but I am wondering if there is a simpler way.
The simpler way is to not do it in FreeMarker :-) This sounds like something controller (or method on model) should be doing rather than view template. That said, you have a few options:
Use ?number built-in within <#attempt> / <#recover> block.
Write a method in one of your model objects to check whether your string into a number and invoke it from the template.
Write a custom directive to do this for you.

Resources