[groovy-user] Groovy way to invoke Class members

87 views
Skip to first unread message

John Bito

unread,
Jan 22, 2010, 8:29:43 PM1/22/10
to us...@groovy.codehaus.org
So I was happily using pattern to initialize a log class member:

private static final Logger log = Logger.getLogger(this.name)

which invokes the getName method of the instance of Class corresponding with the type being initialized.  Somewhat disappointingly, groovyc picks up the instance member if there is one called 'name'. I suppose it may be helpful to flag this at compile time, though it seems it's more of a warning than an error. I do wonder if there's a more groovy way of telling groovyc not to pay attention to the instance members of the current class than

((Class)this).name




Roshan Dawrani

unread,
Jan 22, 2010, 9:49:24 PM1/22/10
to us...@groovy.codehaus.org
If you have an instance member called name, then the line "private static final Logger log = Logger.getLogger(this.name)" should not even let it compile.

So, the following does not compile. Compiler errors out saying "name is declared in a dynamic context, but you tried to access it from a static context."

class Foo {
    private static final String logName = this.name
    def name = "Interfere"
}

This is the behavior I am saying on all 1.6.x / 1.7.x / 1.8.x snapshots. If you remove name field, compiler then sees no clash and in the static usage maps "this" to class instance and then all is well.

Which groovy version r u using?
--
Regards,
Roshan Dawrani
Groovy Developer

John Bito

unread,
Jan 22, 2010, 9:58:22 PM1/22/10
to us...@groovy.codehaus.org
Exactly. It's a little awkward that code that's valid in the class' static context becomes invalid when the instance signatures are changed.

I was just wondering if there's a recommended alternative to
((Class)this).name

Roshan Dawrani

unread,
Jan 22, 2010, 10:20:36 PM1/22/10
to us...@groovy.codehaus.org
You may not like this and it is a result of hit-and-trial more than anything else, but following does the job in both your scenarios:

private static final String logName = getName()

John Bito

unread,
Jan 22, 2010, 10:35:36 PM1/22/10
to us...@groovy.codehaus.org
I guess it's slightly better than ((Class)this).name in that it's fewer characters.  I was just hoping that the use of 'this' in the static context would tell the groovyc to look for a property on the Class instance and not look at the instance members.

Roshan Dawrani

unread,
Jan 22, 2010, 10:38:20 PM1/22/10
to us...@groovy.codehaus.org
Well, it doesn't right now, as is clear from the compilation error. What you say makes sense (to me).

Why don't you open a JIRA?

Jochen Theodorou

unread,
Jan 23, 2010, 5:23:17 AM1/23/10
to us...@groovy.codehaus.org
Roshan Dawrani wrote:
> Well, it doesn't right now, as is clear from the compilation error. What
> you say makes sense (to me).
>
> Why don't you open a JIRA?

and how would you resolve the problem?

bye blackdrag


--
Jochen "blackdrag" Theodorou
The Groovy Project Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email


Roshan Dawrani

unread,
Jan 23, 2010, 5:34:05 AM1/23/10
to us...@groovy.codehaus.org
I don't know yet. Is that a pre-condition for having the issue reported - that we must know beforehand how to solve it?

Isn't the inconsistency observed the reason enough? That

"private static final String logName = this.getName()"

has no problem with an instance level method "getName()" and gets mapped to Foo.class.getName() but

"private static final String logName = this.name"

has a problem with an instance level field "name"?

Roshan Dawrani

unread,
Jan 23, 2010, 5:39:18 AM1/23/10
to us...@groovy.codehaus.org
As a matter of fact I wanted to explore on the lines that in static context this.foo always maps to getClass().foo and see what breaks in groovy code and what kind of issues crop up, and try to take the issue forward one way or another with the reasoning getting captured against the reported JIRA.

Peter Niederwieser

unread,
Jan 23, 2010, 10:54:35 AM1/23/10
to us...@groovy.codehaus.org

It's definitely an inconsistency in the language, and therefore worth
investigating. Personally, I never use "this" to refer to a class, hence I'd
write:
private static final Logger log = Logger.getLogger(MyClass.name)

Cheers,
Peter


Roshan Dawrani-2 wrote:
>
> As a matter of fact I wanted to explore on the lines that in static
> context
> this.foo always maps to getClass().foo and see what breaks in groovy code
> and what kind of issues crop up, and try to take the issue forward one way
> or another with the reasoning getting captured against the reported JIRA.
>

--
View this message in context: http://old.nabble.com/Groovy-way-to-invoke-Class-members-tp27282426p27287240.html
Sent from the groovy - user mailing list archive at Nabble.com.

John Bito

unread,
Jan 23, 2010, 2:19:31 PM1/23/10
to us...@groovy.codehaus.org
Isn't one of the groovy things about Groovy that 'this' has meaning in the static context? It seems the assertion that it's better to always access the class by its name is an argument to remove this feature from the language.

It seems that when in a static context, the compiler could search for static resolutions to the reference ('this.name') before complaining that there is a non-static resolution.  It's nice that the compiler is happy to allow the static reference to getName() to resolve to the Class instance, unlike java; perhaps that's Groovy enough.

Jochen Theodorou

unread,
Jan 23, 2010, 6:11:36 PM1/23/10
to us...@groovy.codehaus.org
Roshan Dawrani wrote:
> I don't know yet. Is that a pre-condition for having the issue reported
> - that we must know beforehand how to solve it?
>
> Isn't the inconsistency observed the reason enough? That
>
> "private static final String logName = this.getName()"
>
> has no problem with an instance level method "getName()" and gets mapped
> to Foo.class.getName() but
>
> "private static final String logName = this.name"
>
> has a problem with an instance level field "name"?

Of course it is no requirement to report it, but is it a bug?

Assuming I have:

class A {
public static name = "xx"
public static foo = this.name
}

what value will foo have? Atm, this is supposed to be "xx", not the
class name. The idea for this compile error was, that if you did mean
what I wrote in my example but forgot the "static" for name, then you
will get an error message. An if we assume you really forgot the static,
then the error message is right too. Also, in the current version
this.name will directly access the field. If you change that to A.name,
and if there is a static name property, then the getter will get accessed.

And since we do the dynamic access if the field/property does not exist,
you could break older code... not that I expect that, but there is a
possibility.

Roshan Dawrani

unread,
Jan 23, 2010, 11:32:05 PM1/23/10
to us...@groovy.codehaus.org
On Sun, Jan 24, 2010 at 4:41 AM, Jochen Theodorou <blac...@gmx.org> wrote:
Assuming I have:

class A {
 public static name = "xx"
 public static foo = this.name
}

what value will foo have? Atm, this is supposed to be "xx", not the class name.

If I have the code


class A {
    public static name = "xx"
    public static foo1 = this.name
    public static foo2 = this.getName()
}

then foo1 gets "xx" and foo2 gets class name "A". That itself looks an issue to me - another inconsistency. Anyway, when the clash is with an existing static variable, then it's a different and existing issue and can be tackled or left as is (whether you see the above behavior as inconsistent or not).
 
The idea for this compile error was, that if you did mean what I wrote in my example but forgot the "static" for name, then you will get an error message. An if we assume you really forgot the static, then the error message is right too.

What if the assumption was wrong and in the code
class A {
    def name = "xx"
    public static logger = Logger.getLog(this.name)
}
the user did want to access the class name? Why shouldn't the compiler let the user do that, when it is projected as a feature that in static context this points to the class instance?
And if the compiler is right in erroring out, then why doesn't this.getName() also error out seeing an instance level getName()?

Also, in the current version this.name will directly access the field. If you change that to A.name, and if there is a static name property, then the getter will get accessed.


Your whole reply is about this.name clashing with an existing "static" field "name", which is not the main point here - when the clash is detected to be with a static field, it can keep the current behavior. The point of this thread is that when the clash is with a non-static field, then why should the compiler complain?

And since we do the dynamic access if the field/property does not exist, you could break older code... not that I expect that, but there is a possibility.

Same as above. In clash with static field, the current behavior can be kept. And when the clash is with a non-static field, there is no possibility of breaking some code because the compiler rejects such code as of now.

Reply all
Reply to author
Forward
0 new messages