Forum: Ruby difference in accessing constant and method defined in eigen class

249c7fd851c5c5ac5a1abdb756472ae1?d=identicon&s=25 Arup Rakshit (my-ruby)
on 2014-03-12 09:40
module M
  class Z
    class << self
      X = "foo"
  def bar; 12 ; end
    end
  end
end

M::Z.bar # => 12
M::Z::X # uninitialized constant M::Z::X (NameError)

When we are able to access the method `bar` but why not the constant `X`
?
7223c62b7310e164eb79c740188abbda?d=identicon&s=25 Xavier Noria (fxn)
on 2014-03-12 10:18
(Received via mailing list)
On Wed, Mar 12, 2014 at 9:40 AM, Arup Rakshit <lists@ruby-forum.com>
wrote:

module M
>
> When we are able to access the method `bar` but why not the constant `X`
> ?


M::Z evaluates to a class object.

That class object has a singleton method called "bar", so you can invoke
the method on the class object.

On the other hand that "X" is stored in the set of constants of the
singleton class of M::Z, let's call it S. M::Z::X looks for "X" in the
constants table of M::Z and its ancestors, since none of them is S, the
lookup fails.
249c7fd851c5c5ac5a1abdb756472ae1?d=identicon&s=25 Arup Rakshit (my-ruby)
on 2014-03-12 11:03
Xavier Noria wrote in post #1139583:
> On Wed, Mar 12, 2014 at 9:40 AM, Arup Rakshit <lists@ruby-forum.com>

> On the other hand that "X" is stored in the set of constants of the
> singleton class of M::Z, let's call it S. M::Z::X looks for "X" in the
> constants table of M::Z and its ancestors, since none of them is S, the
> lookup fails.

Okay. Got it.

module M
  class Z
    Num = 10
    class << self
      Big = 11
  def foo; 12 ; end
    end
  end
end

M::Z.singleton_class::Big # => 12
M::Z.constants.grep(/Num/) # => [:Num]

Why the below didn't give me [:Big] ?

M::Z.singleton_class.constants.grep(/Big/) # => [:Bignum]
7223c62b7310e164eb79c740188abbda?d=identicon&s=25 Xavier Noria (fxn)
on 2014-03-12 12:55
(Received via mailing list)
On Wed, Mar 12, 2014 at 11:03 AM, Arup Rakshit <lists@ruby-forum.com>
wrote:

Xavier Noria wrote in post #1139583:
>   class Z
>
> Why the below didn't give me [:Big] ?
>
> M::Z.singleton_class.constants.grep(/Big/) # => [:Bignum]


It does not make sense, I'd bet this is a bug.
249c7fd851c5c5ac5a1abdb756472ae1?d=identicon&s=25 Arup Rakshit (my-ruby)
on 2014-03-12 13:20
Xavier Noria wrote in post #1139592:
> On Wed, Mar 12, 2014 at 11:03 AM, Arup Rakshit <lists@ruby-forum.com>
> wrote:
>
> Xavier Noria wrote in post #1139583:

> It does not make sense, I'd bet this is a bug.

I expected, I found another *edge case*, as you said always. Should I
then go to raise a bug ticket on this ?

Just this unexpected result gave me much pain since morning. I was not
able to figure out, what's going on there. :(
7223c62b7310e164eb79c740188abbda?d=identicon&s=25 Xavier Noria (fxn)
on 2014-03-12 14:06
(Received via mailing list)
On Wed, Mar 12, 2014 at 1:20 PM, Arup Rakshit <lists@ruby-forum.com>
wrote:

Xavier Noria wrote in post #1139592:
> > On Wed, Mar 12, 2014 at 11:03 AM, Arup Rakshit <lists@ruby-forum.com>
> > wrote:
> >
> > Xavier Noria wrote in post #1139583:
>
> > It does not make sense, I'd bet this is a bug.
>
> I expected, I found another *edge case*, as you said always. Should I
> then go to raise a bug ticket on this ?
>

I believe so.

It is surprising, because these semantics are generic for classes and
modules. I wonder which code could make #constants behave differently
precisely in a singleton class. I'll read the implementation later in
case
something rings a bell.


Just this unexpected result gave me much pain since morning. I was not
> able to figure out, what's going on there. :(


Nevertheless, defining constants in singleton classes is really unusual.
Since the constant resolution algorithm checks nesting and the enclosing
class belongs to the nesting, you normally are done associating the
constant to the regular class, and semantically often makes sense
anyway.
249c7fd851c5c5ac5a1abdb756472ae1?d=identicon&s=25 Arup Rakshit (my-ruby)
on 2014-03-14 20:33
Arup Rakshit wrote in post #1139587:
> Xavier Noria wrote in post #1139583:
>> On Wed, Mar 12, 2014 at 9:40 AM, Arup Rakshit <lists@ruby-forum.com>
>
>> On the other hand that "X" is stored in the set of constants of the
>> singleton class of M::Z, let's call it S. M::Z::X looks for "X" in the
>> constants table of M::Z and its ancestors, since none of them is S, the
>> lookup fails.
>
> Okay. Got it.
>
> module M
>   class Z
>     Num = 10
>     class << self
>       Big = 11
>   def foo; 12 ; end
>     end
>   end
> end
>
> M::Z.singleton_class::Big # => 12

**Note for future readers** - There is a typo in the above line.

M::Z.singleton_class::Big # => 11 (not 12)

> M::Z.constants.grep(/Num/) # => [:Num]
>
> Why the below didn't give me [:Big] ?
>
> M::Z.singleton_class.constants.grep(/Big/) # => [:Bignum]
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.