I'm no doubt missing something obvious but I found this a little
confusing. I would have expected the constant lookup to start in Bar
and therefore succeed. Instead, it appears to start in Base where Foo
is not defined.
In message "Re: Constant lookup starting in superclass, not derived class" on Mon, 11 Sep 2006 21:59:21 +0900, "Chris Roos" <chrisjroos@gmail.com> writes:
I'm no doubt missing something obvious but I found this a little
confusing. I would have expected the constant lookup to start in Bar
and therefore succeed. Instead, it appears to start in Base where Foo
is not defined.
Constants, unlike methods and instance variables, are "quasi"-lexicaly
scoped. (I say "quasi" because a sub class can assign to a constant
without munging its parent class's constant) One way of getting around
this particular situation is to use #const_get. e.g.:
class Base
def foo
p self.class.const_get('Foo')
end
end
···
On Mon, Sep 11, 2006 at 09:59:21PM +0900, Chris Roos wrote:
I'm no doubt missing something obvious but I found this a little
confusing. I would have expected the constant lookup to start in Bar
and therefore succeed. Instead, it appears to start in Base where Foo
is not defined.
I'm no doubt missing something obvious but I found this a little
confusing. I would have expected the constant lookup to start in Bar
and therefore succeed. Instead, it appears to start in Base where Foo
is not defined.
Foo is not in the scope of Base so it cannot be looked up the way you did it. See Matz's explanation how to access it nevertheless. Generally this form of dependency is not desirable, because the base class should be self contained and not depend on any sub classes. In Java you could make Base abstract and add an abstract method that will return a Class instance - but in Ruby there are no abstract classes.
Do you have any suggestions of alternative implementation?
I'd rather not use the self.class.const_get method as it clutters the
code somewhat.
I wonder if I'm trying to refactor two seemingly identical methods
that are in fact different.
class Main1
def Foo; end
def foo
Foo.new
end
end
class Main2
def Foo; end
def foo
Foo.new
end
end
At this point, I created a superclass to hold the common foo method
definition. However, if I had the fully qualified namespace for Foo
(Main1::Foo and Main2::Foo) in each method they would be different and
I wouldn't have moved them. Maybe that is part of my problem.
I understand the point about the base class depending on child classes
not being desirable. What about a module relying on constants defined
elsewhere (does the same apply)?
module Base
def foo
p Foo.new
end
end
class Foo
include Base
class Foo
end
end
Thanks again,
Chris
···
On 9/11/06, Robert Klemme <shortcutter@googlemail.com> wrote:
Chris Roos wrote:
> I'm no doubt missing something obvious but I found this a little
> confusing. I would have expected the constant lookup to start in Bar
> and therefore succeed. Instead, it appears to start in Base where Foo
> is not defined.
>
> class Base
> def foo
> p Foo
> end
> end
>
> class Bar < Base
> class Foo
> end
> end
>
> Bar.new.foo
> # ~> -:3:in `foo': uninitialized constant Base::Foo (NameError)
> # ~> from -:12
>
> Can anyone explain what is happening please?
Foo is not in the scope of Base so it cannot be looked up the way you
did it. See Matz's explanation how to access it nevertheless.
Generally this form of dependency is not desirable, because the base
class should be self contained and not depend on any sub classes. In
Java you could make Base abstract and add an abstract method that will
return a Class instance - but in Ruby there are no abstract classes.
I was bumping against the same wall you are for a while. Later, i
learned how to use meta classes and then realized that they gave me
exactly what i was looking for.
Or to put it more clearly, 'please trim quotations and don't top post.'
Drifting wildly away from the topic, the ambiguity in the original
request reminds me of the signs posted by Southwark Council on some of
their properties: 'Do not exercise or allow your dog to foul the
estate.' (People seem to follow the first half better than the
second.)
Paul.
···
On 11/09/06, Robert Klemme <shortcutter@googlemail.com> wrote:
PS: Please don't top post and trim quotings - that way others can easier
follow threads here.