In the below code
A.new do
hello
C.new
end
You are are trying to create the object of C
, as if it is defined in the scope of the class Object
. No, it is not. class C
is defined inside the scope of module B
. And you need to tell that explicitly as B:C.new
.
Above explanation is for the error -:25:in 'block in ': uninitialized constant C (NameError).
What I cannot understand is how come I have access to C within A ?
Module#constants
has the answer for you :-
Returns an array of the names of the constants accessible in mod. This includes the names of constants in any included modules (example at start of section), unless the inherit parameter is set to
false
.
Look at the example :
module M
X = 10
class D; Y = 10 ;end
end
class C
include M
def initialize
p self.class.constants
end
end
C.new
# >> [:X, :D]
Now applying to your example :
module B
class C
def initialize
'This is C'
end
end
def hello
'hello'
end
end
class A
include B
def initialize(&block)
p self.class.constants
C.new # it will work
#instance_eval(&block)
end
end
A.new do
hello
C.new # but this will throw error.
end
# it confirms that C is accessible, within the method.
# That is the same reason you got the output "This is C"
# >> [:C]
Hope that helps.