What does this syntactically mean in groovy? - groovy

When I do this in groovy shell (2.5.8):
groovy:000> println("s":"s")
[s:s]
===> null
Why did my print statement print a Map (if that's the case)?

The syntax println("s":"s") is an example of passing Named parameters, which are interpreted as a Map.
Like constructors, normal methods can also be called with named parameters. To support this notation, a convention is used where the first argument to the method is a Map.
So you have a parameter named s with a value that is also s and Groovy puts them into a Map for you, per the documentation linked above. You could add additional named parameters to the method call, which will also be added to the Map. This syntax is valid for any method that accepts a Map as its first argument. In the case of println, it accepts Object, and since Map is an Object, named parameters can be passed to this method.

What you see is an omission of square brackets in Map literal in Groovy.
The call can be rewritten as:
println( [ "aa":"bb" ] ) // all brackets in place
println "a":"bb" // no brackets at all
println a:"bb" // a variant, where the left part of : is treated as key in Map Literal

Related

Using Groovy 3 YamlBuilder with Yaml that contains a hyphen

I'm trying to write a Groovy 3 script that uses yamlbuilder to write a yaml file. I have it working on almost everything apart from;
execution:
set-props:
url:http://myhouse.net
port:8000
How do I write a map that allows the use of a hyphen in the name? Following my previous work I foolishly tried;
def setprops=[:]
setprops=(["url":"http://myhouse.net","port":"8000"])
execution.set-props=setprops
Which gives me an error 'The LHS of an assignment should be a variable or a field'.
If I just use execution.setprops then it works fine, but of course the resulting yaml from yaml(execution) is invalid.
I think if the set-props was a a key/value pair then it could go into quote and everything would be good. But because it is part of the structure I don't know what needs to be done.
You can use strings as "methods" and the builder will create your
intermediate structures from them:
import groovy.yaml.YamlBuilder
def b = new YamlBuilder()
b.execution {
"set-props"(
url: "..."
)
}
println b
Or to continue on your example: You can create the whole map and use is as argument, where you want to have that content.
def setprops=["set-props": [url:"..."]]
b.execution(setprops)
Both result in:
---
execution:
set-props:
url: "..."
Note that the first version nests via passed closures and then passes in the map. The second bit just passes a nested map.

Perl6 - What is the $: for in some subroutine Signatures

I came across this error message in another question and I would like to know what is the meaning of the $: part of the signature, please?
Cannot resolve caller index(Str: Str, Any); none of these signatures match:
(Str:D $: Cool:D $needle, *%_)
(Str:D $: Str:D $needle, *%_)
(Str:D $: Cool:D $needle, Cool:D $pos, *%_)
(Str:D $: Str:D $needle, Int:D $pos, *%_)
The $: is two distinct unrelated tokens, a $ and a :, that have been smooshed together.
The $ represents a single item1 aka a scalar2.
The single item / scalar hasn't been given a name, so there's no way to reference it. And there's already enough of a parameter (the Str:D) to let you and the compiler know that this parameter is a scalar (a single string). Either way, the $ is redundant and Elizabeth has made a related change.
The : is a special parameter separator. (The usual parameter separator is a comma ,.)
It may only be used immediately after the first parameter of a method or standalone signature. It may not be used in the signature of a routine that is not a method.
If used as a parameter separator after the first parameter in a signature, it marks that parameter as corresponding to a method's "invocant".
(If not used, the invocant parameter is implicit.)
The corresponding invocant argument will arrive anyway, and be aliased to self, whether or not the signature explicitly lists an invocant parameter. But if the invocant parameter is explicitly specified, it's possible to give it an additional/alternate name and/or explicitly constrain its type.
Crazy over-the-top footnotes for added entertainment. If they confuse you, just forget you ever read them.
1 A single item refers to data that is naturally a single thing, like the number 42, OR data that is naturally a composite thing (like an array) that is being treated like it's a single thing (like an array). (Did you see what I did there?) I like to point out the mnemonic that a $ symbol is like an S (for single) overlaid with an I (for item), or vice-versa. To me this represents the idea of emphasizing the single item nature of any data, hiding any plural aspect even if it's actually an array or other composite data item.
2 "scalar" is a traditional computing term. Wikipedia's Scalar disambiguation page lists "Variable (computing), or scalar, an atomic quantity that can hold only one value at a time" as a definition. Also, a single item aka scalar (all lowercase) is often/usually a Scalar (uppercase S), a special case of a single item that's a Single Item container that contains a Single Item (which can be composite data being treated as a single thing).
The : mark the first argument as an invocant.
my $word = "bananarama";
say $word.index( "r", 0 );
In this case, it indicates the invocant is going to be treated as an scalar, since it's constrained by a single $

Why are calls to containsKey() failing for this groovy map?

I imagine I'm screwing something up with these declarations, but I've got a groovy class with a field defined like this:
Map<String, SomeType> _someField = [:]
I do inserts like this:
_someField.put( someStringVariable, someTypeInstance )
...and then later, when I check whether a key I know has been mapped is present, the check fails:
_someField.containsKey( someStringVariable )
The only way I can get this to succeed is by calling toString(), like so:
_someField.containsKey( someStringVariable.toString() )
I'm using the generic declaration of the map so my IDE gives me auto completion on the value types, so I'd really like (I think) to keep the type information there.
I've tried changing the key type from String to GString, but to no avail. I've tried changing the map initialization from the groovy shorthand [:] to new LinkedHashMap<>, also to no avail.
Any ideas whether I can keep the type information and avoid having to use toString()?
So this was a case where the variable being fed to containsKey() in the instances where it is failing were of type org.codehaus.groovy.runtime.GStringImpl because they were generated by a function that was performing variable expansion on map values, and that function was creating groovy interpolated strings for values instead of Java Strings.
A quick check on the type of the variable confirmed the type problem, and then it was just a matter of tracking back to find the source of the interpolated string.

How to get fields of a Julia object

Given a Julia object of composite type, how can one determine its fields?
I know one solution if you're working in the REPL: First you figure out the type of the object via a call to typeof, then enter help mode (?), and then look up the type. Is there a more programmatic way to achieve the same thing?
For v0.7+
Use fieldnames(x), where x is a DataType. For example, use fieldnames(Date), instead of fieldnames(today()), or else use fieldnames(typeof(today())).
This returns Vector{Symbol} listing the field names in order.
If a field name is myfield, then to retrieve the values in that field use either getfield(x, :myfield), or the shortcut syntax x.myfield.
Another useful and related function to play around with is dump(x).
Before v0.7
Use fieldnames(x), where x is either an instance of the composite type you are interested in, or else a DataType. That is, fieldnames(today()) and fieldnames(Date) are equally valid and have the same output.
suppose the object is obj,
you can get all the information of its fields with following code snippet:
T = typeof(obj)
for (name, typ) in zip(fieldnames(T), T.types)
println("type of the fieldname $name is $typ")
end
Here, fieldnames(T) returns the vector of field names and T.types returns the corresponding vector of type of the fields.

Get argument names in String Interpolation in Scala 2.10

As of scala 2.10, the following interpolation is possible.
val name = "someName"
val interpolated = s"Hello world, my name is $name"
Now it is also possible defining custom string interpolations, as you can see in the scala documentation in the "Advanced usage" section here http://docs.scala-lang.org/overviews/core/string-interpolation.html#advanced_usage
Now then, my question is... is there a way to obtain the original string, before interpolation, including any interpolated variable names, from inside the implicit class that is defining the new interpolation for strings?
In other words, i want to be able to define an interpolation x, in such a way that when i call
x"My interpolated string has a $name"
i can obtain the string exactly as seen above, without replacing the $name part, inside the interpolation.
Edit: on a quick note, the reason i want to do this is because i want to obtain the original string and replace it with another string, an internationalized string, and then replace the variable values. This is the main reason i want to get the original string with no interpolation performed on it.
Thanks in advance.
Since Scala's string interpolation can handle arbitrary expressions within ${} it has to evaluate the arguments before passing them to the formatting function. Thus, direct access to the variable names is not possible by design. As pointed out by Eugene, it is possible to get the name of a plain variable by using macros. I don't think this is a very scalable solution, though. After all, you'll lose the possibility to evaluate arbitrary expressions. What, for instance, will happen in this case:
x"My interpolated string has a ${"Mr. " + name}"
You might be able to extract the variable name by using macros but it might get complicated for arbitrary expressions. My suggestions would be: If the name of your variable should be meaningful within the string interpolation, make it a part of the data structure. For example, you can do the following:
case class NamedValue(variableName: String, value: Any)
val name = NamedValue("name", "Some Name")
x"My interpolated string has a $name"
The objects are passed as Any* to the x. Thus, you now can match for NamedValue within x and you can do specific things depending on the "variable name", which now is part of your data structure. Instead of storing the variable name explicitly you could also exploit a type hierarchy, for instance:
sealed trait InterpolationType
case class InterpolationTypeName(name: String) extends InterpolationType
case class InterpolationTypeDate(date: String) extends InterpolationType
val name = InterpolationTypeName("Someone")
val date = InterpolationTypeDate("2013-02-13")
x"$name is born on $date"
Again, within x you can match for the InterpolationType subtype and handle things according to the type.
It seems that's not possible. String interpolation seems like a compile feature that compiles the example to:
StringContext("My interpolated string has a ").x(name)
As you can see the $name part is already gone. It became really clear for me when I looked at the source code of StringContext: https://github.com/scala/scala/blob/v2.10.0/src/library/scala/StringContext.scala#L1
If you define x as a macro, then you will be able to see the tree of the desugaring produced by the compiler (as shown by #EECOLOR). In that tree, the "name" argument will be seen as Ident(newTermName("name")), so you'll be able to extract a name from there. Be sure to take a look at macro and reflection guides at docs.scala-lang.org to learn how to write macros and work with trees.

Resources