Home > Groovy > Groovy Strings n Things

Groovy Strings n Things

November 17, 2008 Leave a comment Go to comments

I’d like to take a moment to speculate on one of our previous posts,  A quirk in Groovy maps and GString coercion.

This post brought up a good example of some buggy behavior in Groovy when it comes to GStrings and Maps.  However, I don’t think the problem is in the Map, but in mixing/matching java.lang.String’s with groovy.lang.GString’s, and in particular on existing Java class methods that expect Strings.  Taking the two examples from the previous post..  

Exhibit A:

println map[“$aVar”] //still good, this outputs x.

println map.get(”$aVar”) // oh snap! this outputs null!

 

Exhibit B:

println ‘a’ == “$aVar” // true

println ‘a’.equals(”$aVar”) // double snap!! it’s false!!

I think there’s a pattern..  

In the first part of both of these example, we’re taking advantage of the operator overloading that Groovy provides and mix/matching java.lang.Strings and groovy.lang.GStrings, which seem to play nicely together in those cases.  It appears that the GStrings are being evaluated before being coerced into Strings.  The coercion must be happening at runtime for the dynamic GString to have it’s $value translated and put into the resulting String.

However, in the later case of both of these examples, we’re calling existing methods on existing Java classes (java.util.Map and java.lang.String).   These methods take Strings not GStrings.  In these cases, it looks like Groovy still coerces these GStrings into Strings, but my hunch is that it must do so at compile time in order to play nicely with statically typed Java methods on statically typed java objects.  This would mean that it wouldn’t have enough information at that time to replace the $aVar with it’s dynamic runtime value and therefore doesn’t know what else to do but use the literal String value.

This is all speculation of course, but this model makes sense of what we’re seeing here.  Is there anyone who knows enough about the internals of Groovy to confirm or deny this speculation?

Advertisements
Tags: ,
  1. November 26, 2008 at 4:49 pm

    Yep, you’re right. There are some java things that are still a little picky about what they get and GStrings aren’t quite equal enough without a little bit of additional hinting. You can use a .toString() or an “as String” on a GString for those situations:

    def aVar = ‘a’
    def map = [(aVar):’x’]

    assert ‘x’ == map[“$aVar”]
    assert null == map.get(“$aVar”)
    assert ‘x’ == map.get(“$aVar”.toString())
    assert ‘x’ == map.get(“$aVar” as String)

    assert true == (‘a’ == “$aVar”)
    assert false == (‘a’.equals(“$aVar”))
    assert true == (‘a’.equals(“$aVar”.toString()))
    assert true == (‘a’.equals(“$aVar” as String))

  2. November 26, 2008 at 9:58 pm

    Thanks, Ted!

  1. August 13, 2011 at 11:55 am
  2. October 7, 2012 at 11:14 am

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: