Difference in accessing constant and method defined in eigen class

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`
?

···

--
Posted via http://www.ruby-forum.com/.

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`
?

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.

···

On Wed, Mar 12, 2014 at 9:40 AM, Arup Rakshit <lists@ruby-forum.com> wrote:

Xavier Noria wrote in post #1139583:

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]

···

On Wed, Mar 12, 2014 at 9:40 AM, Arup Rakshit <lists@ruby-forum.com>

--
Posted via http://www.ruby-forum.com/\.

Xavier Noria wrote in post #1139583:

···

On Wed, Mar 12, 2014 at 11:03 AM, Arup Rakshit <lists@ruby-forum.com> wrote:

> 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]

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

Arup Rakshit wrote in post #1139587:

Xavier Noria wrote in post #1139583:

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)

···

On Wed, Mar 12, 2014 at 9:40 AM, Arup Rakshit <lists@ruby-forum.com>

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

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

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

--
Posted via http://www.ruby-forum.com/\.

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. :frowning:

--
Posted via http://www.ruby-forum.com/\.

Xavier Noria wrote in post #1139592:

>
> 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. :frowning:

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.

···

On Wed, Mar 12, 2014 at 1:20 PM, Arup Rakshit <lists@ruby-forum.com> wrote:

> On Wed, Mar 12, 2014 at 11:03 AM, Arup Rakshit <lists@ruby-forum.com> > > wrote: