Module_eval is an instance method?

pickaxe2 lists module_eval as an instance method of Module. But:

num = 10
puts Object.module_eval(‘num’)
—> 10

puts self
–>main

puts self.class
–>Object

puts self.module_eval(‘num’)
undefined method `module_eval’ for main:Object (NoMethodError)

  1. Why am I able to call module_eval with a class name, i.e. Object?

  2. Why can’t I call module_eval with an instance of Object?

module_eval is a instance method of Module.

It is available to anything that is a Module.

irb(main):001:0> Object.is_a?(Module)
=> true
irb(main):002:0> String.is_a?(Module)
=> true
irb(main):003:0> self.is_a?(Module)
=> false

Paul McMahon wrote:

module_eval is a instance method of Module.

It is available to anything that is a Module.

Thanks.

Paul McMahon wrote:

module_eval is a instance method of Module.

It is available to anything that is a Module.

irb(main):001:0> Object.is_a?(Module)
=> true
irb(main):002:0> String.is_a?(Module)
=> true
irb(main):003:0> self.is_a?(Module)
=> false

Ok, how do you explain this output:

def meth1
Object.module_eval(‘num’)
end

num = 10
Object.module_eval(‘num’)
–>10

meth1
–>
module_eval': undefined local variable or methodnum’ for Object:Class
(NameError)

According to pickaxe2, p. 393:

“When we define methods, we’re actually creating (private) instance
methods for class Object.”

What about top level variables?

meth1
–>
module_eval': undefined local variable or methodnum’ for Object:Class
(NameError)

num is not in the scope of meth1 or of the Object class so resolution
fails. If you use a global variable it works fine.

$num = 10
def meth1
Object.module_eval(’$num’)
end

Regards,
Jordan

Jordan Callicoat wrote:

meth1
–>
module_eval': undefined local variable or methodnum’ for Object:Class
(NameError)

num is not in the scope of meth1 or of the Object class so resolution
fails. If you use a global variable it works fine.

It’s not in the scope of the Object class? Then why does this work:

num = 10
Object.module_eval(‘num’)
–>10

Ps. You could also just use instance_eval…

$num = 10
def meth1
instance_eval(’$num’)
end

On Nov 26, 2:36 am, 7stud – [email protected] wrote:

It’s not in the scope of the Object class? Then why does this work:

num = 10
Object.module_eval(‘num’)
–>10

According to the method resolution order (MRO), ruby looks for the
attribute in the local scope first, then in the containing scope which
is exposed to the local scope. So in this case, num is the in local
scope for Object#module_eval, i.e., the local scope is self (which is
“main”). If it’s not in the local scope, then in this instance the
exposed containing scope is the Object class. Since ‘num’ is not in
the Object class, if you call Object.module_eval(‘num’) w/o defining
num first, you get the same error. In other words, when you call
Object#module_eval from the top-level, the local scope is the top-
level. But when you call it from inside a function, the local scope is
the function. You can’t access the higher scope of main from within
the lower scope of the function. To do that you need to use a global
variable, which exposes itself to all of the lower scopes of main.
Hmmm…I’m probably not explaining that very well. Basically, anything
you define in the top-level scope is only accessible from the top-
level scope. For nested scopes you either have to pass the data as a
parameter of the function, or use a global variable. Hope that makes
some sense. I’m tired, so forgive me if I’m being incoherent!

Regards,
Jordan

On Nov 25, 2007, at 11:43 PM, 7stud – wrote:

=> false

meth1
–>
module_eval': undefined local variable or methodnum’ for
Object:Class
(NameError)

According to pickaxe2, p. 393:

“When we define methods, we’re actually creating (private) instance
methods for class Object.”

Ruby pretty much says exactly what’s going here: num is not a local
variable or a method accessible inside the scope of meth1.

What about top level variables?

I don’t reccomend this, but you can get at them:

#!/usr/bin/env ruby -wKU

def print_num
puts eval(“num”, TOPLEVEL_BINDING)
end

num = 10
print_num

END

James Edward G. II