Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Constant lookup starting in superclass, not derived class

Reply
Thread Tools

Constant lookup starting in superclass, not derived class

 
 
Chris Roos
Guest
Posts: n/a
 
      09-11-2006
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?

Cheers,

Chris

 
Reply With Quote
 
 
 
 
Yukihiro Matsumoto
Guest
Posts: n/a
 
      09-11-2006
Hi,

In message "Re: Constant lookup starting in superclass, not derived class"
on Mon, 11 Sep 2006 21:59:21 +0900, "Chris Roos" <> 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.
|
|class Base
| def foo
| p Foo
| end
|end

use "self.class::Foo" instead of plain "Foo".

matz.


 
Reply With Quote
 
 
 
 
Robert Klemme
Guest
Posts: n/a
 
      09-11-2006
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.

Kind regards

robert
 
Reply With Quote
 
Logan Capaldo
Guest
Posts: n/a
 
      09-11-2006
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.
>
> 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?

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

 
Reply With Quote
 
Chris Roos
Guest
Posts: n/a
 
      09-11-2006
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 <> 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.
>
> Kind regards
>
> robert
>
>


 
Reply With Quote
 
Robert Klemme
Guest
Posts: n/a
 
      09-11-2006
Chris Roos wrote:
> Do you have any suggestions of alternative implementation?


Depends on what you want to do. If you just want to create instances
then you can just use a method.

class Base
def something
f = create_foo
# use f
end
end

class Derived < Base
class Foo
end

def create_foo(*a,&b)
Foo.new(*a,&b)
end
end

Or, if you want to do it more fancy you can define create_foo in the
base class and have it return nil or raise an exception.

Kind regards

robert


PS: Please don't top post and trim quotings - that way others can easier
follow threads here.
 
Reply With Quote
 
Paul Battley
Guest
Posts: n/a
 
      09-11-2006
On 11/09/06, Robert Klemme <> wrote:
> PS: Please don't top post and trim quotings - that way others can easier
> follow threads here.


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.

 
Reply With Quote
 
bpettichord@gmail.com
Guest
Posts: n/a
 
      09-12-2006
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.

http://whytheluckystiff.net/articles...esClearly.html

Bret


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
3 ESSENTIAL TOOLS FOR STARTING AND MAINTAINING...3 ESSENTIAL TOOLSFOR STARTING AND MAINTAINING...3 ESSENTIAL TOOLS FOR STARTING ANDMAINTAINING... Oanh Bui C++ 0 04-27-2009 12:51 PM
3 ESSENTIAL TOOLS FOR STARTING AND MAINTAINING...3 ESSENTIAL TOOLSFOR STARTING AND MAINTAINING...3 ESSENTIAL TOOLS FOR STARTING ANDMAINTAINING... Oanh Bui C Programming 0 04-27-2009 12:51 PM
3 ESSENTIAL TOOLS FOR STARTING AND MAINTAINING...3 ESSENTIAL TOOLSFOR STARTING AND MAINTAINING...3 ESSENTIAL TOOLS FOR STARTING ANDMAINTAINING... Oanh Bui Python 0 04-27-2009 12:46 PM
Derived::Derived(const Base&) and Derived& operator=(const Base&) developereo@hotmail.com C++ 1 05-23-2007 01:44 PM
Derived::Derived(const Base&) and Derived& operator=(const Base&) developereo@hotmail.com C++ 1 05-23-2007 12:07 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57