Instance_eval/class_eval including/extending modules

Consider the following example:

  module SomeModule
    def some_method
       puts "Some Method - #{self}"
    end
  end

  class SomeClass
    def self.metaclass
      class << self; self; end
    end
  end

  SomeClass.instance_eval {include SomeModule} # instance method
  SomeClass.instance_eval {extend SomeModule} # singleton method (class
method)
  SomeClass.metaclass.instance_eval {include SomeModule} # class method

Using instance_eval on SomeClass sets the "ghost class" to be the
current class, so using include shouldn't put the methods on "ghost
class" instead of SomeClass (SomeClass class methods)? In this case
using instance_eval or class_eval has the same result, depending only if
we're using include or extend.

AFAIK the "problem" has to do with value of self, because private
methods are invoked on self (default receiver), so using instance_eval
or class_eval won't matter as self will be SomeClass in both cases.
That's why calling include in instance_eval/class_eval on metaclass
(self is now the "ghost class") is the same as using extend when self is
SomeClass.

I'm using Ruby 1.8.6 and at least to me this seems kind of a strange
behaviour because using def or define_method will have different results
if we use instance_eval. Does Ruby 1.9 maintains this behaviour?

In my humble opinion would make more sense if instance_eval/class_eval
maintain the same behaviour on all methods and not the "special"
behaviour on private methods. Can someone enlight me?

···

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

HI --

Consider the following example:

module SomeModule
   def some_method
      puts "Some Method - #{self}"
   end
end

class SomeClass
   def self.metaclass
     class << self; self; end
   end
end

SomeClass.instance_eval {include SomeModule} # instance method
SomeClass.instance_eval {extend SomeModule} # singleton method (class
method)
SomeClass.metaclass.instance_eval {include SomeModule} # class method

Using instance_eval on SomeClass sets the "ghost class" to be the
current class, so using include shouldn't put the methods on "ghost
class" instead of SomeClass (SomeClass class methods)? In this case
using instance_eval or class_eval has the same result, depending only if
we're using include or extend.

I'm not sure what you mean by "ghost class". I think that might be an
unnecessary extra term.

AFAIK the "problem" has to do with value of self, because private
methods are invoked on self (default receiver), so using instance_eval
or class_eval won't matter as self will be SomeClass in both cases.
That's why calling include in instance_eval/class_eval on metaclass
(self is now the "ghost class") is the same as using extend when self is
SomeClass.

That's true all the time: mixing a module into an object's singleton
class is the same as extending the object with that module. In both
cases, the module gets inserted in the object's method lookup path
between the singleton class and the original class.

I'm using Ruby 1.8.6 and at least to me this seems kind of a strange
behaviour because using def or define_method will have different results
if we use instance_eval. Does Ruby 1.9 maintains this behaviour?

Yes, and that's really part of the point of having both instance_eval
and class_eval. I don't think there's any advantage to merging them
into one behavior. Just choose the one you need in a given case.

In my humble opinion would make more sense if instance_eval/class_eval
maintain the same behaviour on all methods and not the "special"
behaviour on private methods. Can someone enlight me?

I don't really see the anomaly you're seeing, but let me outline the
rules that are followed (which, in the case of instance_eval, have
nothing to do with whether or not the object is a class), and maybe
that will clear it up or at least simplify it.

obj.instance_eval {...} sets self to obj during the block. Instance
methods defined in the block are singleton methods of obj (i.e.,
instance methods of obj's singleton class).

c.class_eval sets self to c during the block. Instance methods defined
in the block are instance methods of c.

I think everything you're seeing can be accounted for by those rules.

David

···

On Sun, 31 Aug 2008, Pedro Silva wrote:

--
Rails training from David A. Black and Ruby Power and Light:
   Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL
   Advancing with Rails January 19-22 Fort Lauderdale, FL *
   * Co-taught with Patrick Ewing!
See http://www.rubypal.com for details and updates!

David, thanks for your reply.

I'm not sure what you mean by "ghost class". I think that might be an
unnecessary extra term.

What I meant by "ghost class" was singleton class or eigenclass. I've
already seen different names for the class that Ruby creates when we use
instance_eval or define singleton methods.

Yes, and that's really part of the point of having both instance_eval
and class_eval. I don't think there's any advantage to merging them
into one behavior. Just choose the one you need in a given case.

I'm not saying they should have the same behaviour in that sense, I was
trying to say that they should have the same behaviour no matter what is
the method visibility - private vs others. As matter of fact I think
using instance_eval or class_eval with include/extend should have
different results.

SomeClass.instance_eval {include SomeModule} has the same result as
SomeClass.class_eval {include SomeModule}

I don't really see the anomaly you're seeing, but let me outline the
rules that are followed (which, in the case of instance_eval, have
nothing to do with whether or not the object is a class), and maybe
that will clear it up or at least simplify it.

The example above showed me the "special case" between private methods
and other methods. Let me see if I can write an example that shows what
I'm trying to say. I think the best way is using def vs define_method.

  SomeClass.instance_eval { def class_method; puts "Class Method"; end }
  SomeClass.instance_eval do
    define_method(:instance_method) {puts "Instance Method"}
  end

  SomeClass.class_method
  SomeClass.new.instance_method

At least for me this is not something I would expect. When I define a
method using instance_eval I expect to have a singleton method (class
method in this case). The problem here has to do with self and what is
the current class, self is still SomeClass so define_method creates an
instance method, but because current class is the singleton class, using
def is the same as creating a class method. I guess this happen because
define_method is a private method. So in my opinion private methods have
different treatment from regular methods.

I hope I expressed myself in the right manner what I was trying to say
(i'm not a native english speaker, portuguese actually :p). If you could
tell me what you think about that I'll appreciate that.

···

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

Hi --

David, thanks for your reply.

I'm not sure what you mean by "ghost class". I think that might be an
unnecessary extra term.

What I meant by "ghost class" was singleton class or eigenclass. I've
already seen different names for the class that Ruby creates when we use
instance_eval or define singleton methods.

Yes, and that's really part of the point of having both instance_eval
and class_eval. I don't think there's any advantage to merging them
into one behavior. Just choose the one you need in a given case.

I'm not saying they should have the same behaviour in that sense, I was
trying to say that they should have the same behaviour no matter what is
the method visibility - private vs others. As matter of fact I think
using instance_eval or class_eval with include/extend should have
different results.

SomeClass.instance_eval {include SomeModule} has the same result as
SomeClass.class_eval {include SomeModule}

I don't really see the anomaly you're seeing, but let me outline the
rules that are followed (which, in the case of instance_eval, have
nothing to do with whether or not the object is a class), and maybe
that will clear it up or at least simplify it.

The example above showed me the "special case" between private methods
and other methods. Let me see if I can write an example that shows what
I'm trying to say. I think the best way is using def vs define_method.

SomeClass.instance_eval { def class_method; puts "Class Method"; end }
SomeClass.instance_eval do
   define_method(:instance_method) {puts "Instance Method"}
end

SomeClass.class_method
SomeClass.new.instance_method

At least for me this is not something I would expect. When I define a
method using instance_eval I expect to have a singleton method (class
method in this case). The problem here has to do with self and what is
the current class, self is still SomeClass so define_method creates an
instance method, but because current class is the singleton class, using
def is the same as creating a class method. I guess this happen because
define_method is a private method. So in my opinion private methods have
different treatment from regular methods.

I hope I expressed myself in the right manner what I was trying to say
(i'm not a native english speaker, portuguese actually :p). If you could
tell me what you think about that I'll appreciate that.

I don't think there's any special case for private methods. They get
called on 'self', just as they always do. And if you instance_eval a
class, "def" does exactly what it does when you instance_eval any
object: it creates a singleton method.

Keep in mind that so-called "class methods" are essentially just
singleton methods of instances of Class. (The only special case
behavior is the fact that subclasses of class C can call class C's
class methods.)

Like most questions in Ruby, it comes down to: classes are objects too
:slight_smile: I don't think instance_eval does anything special with classes.
The only special thing you'd want to do is to be able to create
instance methods, and class_eval handles that case.

David

···

On Mon, 1 Sep 2008, Pedro Silva wrote:

--
Rails training from David A. Black and Ruby Power and Light:
   Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL
   Advancing with Rails January 19-22 Fort Lauderdale, FL *
   * Co-taught with Patrick Ewing!
See http://www.rubypal.com for details and updates!

Thanks once again for the fast reply,

I don't think there's any special case for private methods. They get
called on 'self', just as they always do. And if you instance_eval a
class, "def" does exactly what it does when you instance_eval any
object: it creates a singleton method.

In my opinion define_method and def executed in the same context should
have the same behaviour, but they don't. The reason def creates a
singleton method is because the current class is set to the singleton
class so there's where the method will be defined, but self remains the
instance_eval receiver.

Keep in mind that so-called "class methods" are essentially just
singleton methods of instances of Class. (The only special case
behavior is the fact that subclasses of class C can call class C's
class methods.)

I know that, that's why I said singleton methods (class methods).

Like most questions in Ruby, it comes down to: classes are objects too
:slight_smile: I don't think instance_eval does anything special with classes.
The only special thing you'd want to do is to be able to create
instance methods, and class_eval handles that case.

I guess I was unable to express correctly my point. I know that
class_eval lets create instance methods (that's why the receiver must be
a class) and instance_eval singleton methods (on classes means class
methods). My problem is having instance_eval with def creating singleton
methods but with define_method creating instance methods. I expected to
have def and define_method to have the same result on the same context,
but they don't.

···

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

Hi --

Thanks once again for the fast reply,

I don't think there's any special case for private methods. They get
called on 'self', just as they always do. And if you instance_eval a
class, "def" does exactly what it does when you instance_eval any
object: it creates a singleton method.

In my opinion define_method and def executed in the same context should
have the same behaviour, but they don't. The reason def creates a
singleton method is because the current class is set to the singleton
class so there's where the method will be defined, but self remains the
instance_eval receiver.

Yes, that's the rule, and it's followed for all objects. It sounds
like you want a special case for instance_eval on class objects, so
that they somehow don't realize that define_method is being called on
them, and I don't think that's a good idea. It's better to keep the
definition of the instance_eval context consistent: self is swapped to
the receiver, and 'def' applies to the receiver's singleton class.
That accounts for everything that currently happens, and it makes no
difference whether it's a class object or some other object.

Keep in mind that so-called "class methods" are essentially just
singleton methods of instances of Class. (The only special case
behavior is the fact that subclasses of class C can call class C's
class methods.)

I know that, that's why I said singleton methods (class methods).

Like most questions in Ruby, it comes down to: classes are objects too
:slight_smile: I don't think instance_eval does anything special with classes.
The only special thing you'd want to do is to be able to create
instance methods, and class_eval handles that case.

I guess I was unable to express correctly my point. I know that
class_eval lets create instance methods (that's why the receiver must be
a class) and instance_eval singleton methods (on classes means class
methods). My problem is having instance_eval with def creating singleton
methods but with define_method creating instance methods. I expected to
have def and define_method to have the same result on the same context,
but they don't.

I understand your point, but I don't like the idea of introducing the
special case. Remember that the point of define_method is that it's a
method, with method semantics and local scope in its code-block. It's
not supposed to be identical to def, and it has very different uses.

For the case where self is the class and define_method and def behave
similarly, there's class_eval. Instead of having instance_eval treat
classes as a special case, which would be inconsistent and confusing,
there's a separate method for doing something very similar to a
'class' block, but with a code block.

David

···

On Mon, 1 Sep 2008, Pedro Silva wrote:

--
Rails training from David A. Black and Ruby Power and Light:
   Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL
   Advancing with Rails January 19-22 Fort Lauderdale, FL *
   * Co-taught with Patrick Ewing!
See http://www.rubypal.com for details and updates!

Really fast this time. :wink:

For the case where self is the class and define_method and def behave
similarly, there's class_eval. Instead of having instance_eval treat
classes as a special case, which would be inconsistent and confusing,
there's a separate method for doing something very similar to a
'class' block, but with a code block.

I understand, I guess I can't distinguish very well self from current
class concept. Can you explain the difference?

One last question to see if I understand all this correctly. Private
methods are invoked on self, other non-private methods are invoked on
current class?

···

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

I must say that I also find the difference between
instance_eval/class_eval and include/extend extremely confusing.

If someone clearly knows the fundamental rules, please please share.

Here's my understanding:

def myMethod; end
  -creates a method "myMethod" callable by instances of self.

Here's a list of situations that I'm having trouble with:

1) class Klass
     def myMethod; end
   end

  -self is equal to Klass
  -so myMethod() is callable by Klass.new

2) Klass.instance_eval {def myMethod; end}

-self is equal to Klass
-so myMethod() is callable by Klass.new <-- this isn't true

What's wrong with my understanding? I think I'm not understanding def
correctly.

···

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

Ruby has two separate concepts: self, the current object, and 'the current class', which isn't represented by an externally visible variable. Methods are stored in the later, independent of the value of self. It _is_ confusing, but you can always remember that class_eval creates instance methods and instance_eval creates class methods. There are actually good reasons why this is so.

If you want to get deeper into this, <pimp>I could recommend a certain set of screencasts...</pimp>

Dave

···

On Aug 31, 2008, at 9:15 PM, Patrick Li wrote:

I must say that I also find the difference between
instance_eval/class_eval and include/extend extremely confusing.

If someone clearly knows the fundamental rules, please please share.

Here's my understanding:

def myMethod; end
-creates a method "myMethod" callable by instances of self.

Here's a list of situations that I'm having trouble with:

1) class Klass
    def myMethod; end
  end

-self is equal to Klass
-so myMethod() is callable by Klass.new

2) Klass.instance_eval {def myMethod; end}

-self is equal to Klass
-so myMethod() is callable by Klass.new <-- this isn't true

What's wrong with my understanding? I think I'm not understanding def
correctly.

# I must say that I also find the difference between
# instance_eval/class_eval and include/extend extremely confusing.
# If someone clearly knows the fundamental rules, please please share.
# Here's my understanding:
# def myMethod; end
# -creates a method "myMethod" callable by instances of self.
# Here's a list of situations that I'm having trouble with:
# 1) class Klass
# def myMethod; end
# end
# -self is equal to Klass
# -so myMethod() is callable by Klass.new

generally, callable by instances of Klass

# 2) Klass.instance_eval {def myMethod; end}
# -self is equal to Klass
# -so myMethod() is callable by Klass.new

no.
the instance here is Klass, not those created/instanciated w Klass.new. So you are creating a class method for Klass. Remember, classes are objects too, ergo there are class methods too.

# What's wrong with my understanding? I think I'm not understanding def
# correctly.

observe eg,

class Klass
  def mymethod; end
end
#=> nil

k=Klass.new
#=> #<Klass:0x28e1ff0>

k.mymethod
#=> nil

ok. fine.
let's try the other way, ie instance_eval.

k.instance_eval{def mymethod3; end}
#=> nil

k.mymethod3
#=> nil

fine still.
now let us try it for Klass itself.

Klass.mymethod
NoMethodError: undefined method `mymethod' for Klass:Class

oops :wink:
maybe, we can do it w mymethod3

Klass.mymethod3
NoMethodError: undefined method `mymethod3' for Klass:Class

oops still :wink:

Ok. let us define a method that works only for Klass.

Klass.instance_eval{def mymethod2; end}
#=> nil

k.mymethod2
NoMethodError: undefined method `mymethod2' for #<Klass:0x28e1ff0>

heheh, it does not work for instances/creations of Klass.
now, let us test it for Klass itself.

Klass.mymethod2
#=> nil

ah, we see.

hth.
kind regards -botp

···

From: Patrick Li [mailto:patrickli_2001@hotmail.com]

Ahhh... now it comes together. Thank you so much.

so here's a quick revision of my understanding:

I'm gonna call the 'the current class' selfClass.

1)
class Klass
  <-- self is Klass
  <-- selfClass is also Klass
end

2)
def myMethod; end <-- creates myMethod(), callable by selfClass.new

3)
obj.instance_eval <-- sets self to obj, sets selfClass to obj's
metaclass

4)
obj.class_eval <-- sets self to obj, AND sets selfClass to obj

5)
include myModule <-- evaluates the instructions in myModule, underneath
selfClass

6)
extend myModule <-- evaluates the instructions in myModule, underneath
self

Does that seem correct now? Thanks for your help by the way. That's
quite a bit more clear now.

···

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

No evaluation takes place. The module is already "compiled", and Ruby simply links a proxy for that module in to the parent class chain for either the class or metaclass. That way, module functionality is shared between multiple classes/objects that include/extend the module.

Dave

···

On Aug 31, 2008, at 9:50 PM, Patrick Li wrote:

5)
include myModule <-- evaluates the instructions in myModule, underneath
selfClass

6)
extend myModule <-- evaluates the instructions in myModule, underneath
self

Does that seem correct now? Thanks for your help by the way. That's
quite a bit more clear n

Now that I have a firmer grasp on Ruby's object system, is it possible
to combine some of these methods, so that they're easier to understand?

Here's some changes that can be made:

Let me know what you think
  -Patrick

What it does:
Combines eval/instance_eval/class_eval into one consistent method
Combines include/extend into one consistent method

Changes:

eval(proc)
-eval is now a method of Object. This ALWAYS sets self to the receiver
object,

and then evaluates proc.

def myMethod
-def is now a method of Module. This creates a method named myMethod()
that

can be called by instances of the receiver.

Consequences: This means that if self is not a subclass of Module, you
cannot

call def. Instead I propose a metaclass method that returns an objects

metaclass.

So instead of:
obj.instance_eval do
  def myMethod; end
end

you MUST do:
obj.metaclass.instance_eval do
  def myMethod; end
end

include myModule
-becomes a method of Object. This method puts the method definitions in
myModule into the receiver object.

···

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

HI --

Now that I have a firmer grasp on Ruby's object system, is it possible
to combine some of these methods, so that they're easier to understand?

Here's some changes that can be made:

Let me know what you think
-Patrick

What it does:
Combines eval/instance_eval/class_eval into one consistent method
Combines include/extend into one consistent method

It's not right to say that these things are inconsistent. They're all
different from each other, and they all do things that make sense and
are needed frequently. include and extend are related, but they're not
in conflict; they're complementary, and they both do extremely useful
things.

Changes:

eval(proc)
-eval is now a method of Object. This ALWAYS sets self to the receiver
object,

and then evaluates proc.

def myMethod
-def is now a method of Module. This creates a method named myMethod()
that

can be called by instances of the receiver.

Consequences: This means that if self is not a subclass of Module, you
cannot

call def. Instead I propose a metaclass method that returns an objects

metaclass.

Join the club :slight_smile: Well, I call it Object#singleton_class, but there's
been a request pending for this method for years.

So instead of:
obj.instance_eval do
def myMethod; end
end

you MUST do:
obj.metaclass.instance_eval do
def myMethod; end
end

Why? What's the advantage of taking away the current instance_eval
scenario?

include myModule
-becomes a method of Object. This method puts the method definitions in
myModule into the receiver object.

I think you're trying to squeeze things together too tightly. Right
now they're pretty well-engineered to handle the major use-cases and
not to overlap with each other. I'd recommend living with them a
little longer, and playing around with them a bit -- I think you'll
see that they're all pulling their weight pretty well.

David

···

On Mon, 1 Sep 2008, Patrick Li wrote:

--
Rails training from David A. Black and Ruby Power and Light:
   Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL
   Advancing with Rails January 19-22 Fort Lauderdale, FL *
   * Co-taught with Patrick Ewing!
See http://www.rubypal.com for details and updates!