Self and Current Class

I know that Ruby always keeps track of two concepts: self and current
class.

The programmer only can access the first one, that tracks the current
object. I know that self is the default receiver when invoking methods
and that obviously affects the way Ruby processes the code. Fortunately
self I understand quite well.

My doubt comes with the current class concept. I know that when we use
instance_eval, self is set to the receiver and current class to the
singleton class, that's why it allows to define singleton methods. I
would like to undestand how current class is altered by Ruby because
there's no way to print stuff and see what happens.

Can anyone enumerate which cases Ruby uses current class and a general
rule for current class status?

Pedro.

···

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

Pedro Silva wrote:

I know that Ruby always keeps track of two concepts: self and current
class.

The programmer only can access the first one, that tracks the current
object. I know that self is the default receiver when invoking methods
and that obviously affects the way Ruby processes the code. Fortunately
self I understand quite well.

My doubt comes with the current class concept. I know that when we use
instance_eval, self is set to the receiver and current class to the
singleton class, that's why it allows to define singleton methods. I
would like to undestand how current class is altered by Ruby because
there's no way to print stuff and see what happens.

Can anyone enumerate which cases Ruby uses current class and a general
rule for current class status?

Pedro.

Hello.

Well, at first I thought that you can always check the current class
using
class<<self;self;end
but now I see I was wrong. Good I realised it before posting.

In fact, most of the time this is the way to check the current class.
Inside x.instance_eval{} self is set to x, and the current class is set
to class<<x;self;end (that is, x's eigenclass), so when you def a method
there, it will become a method of x (you will be able to call it by
x.method, no matter if x is a regular object or a class), and the class
that will hold the method is the x's eigenclass - it will be visible in
class<<x;instance_methods;end.

But there is an exception from this rule. Inside class declaration:
class K
#here
end
self is set to the class (that is, K), class<<self;self;end is of course
the class'es eigenclass, but if you def a method now, it will not become
the method that you can call by K.method, but it will become an instance
method of the class K, and that means that K was the current class at
the time of declaring the method, even though it was self at the same
time.

I guess it works alike inside modules.

So I guess the general rule is: inside module declaration, both self and
current class are set to the module we're declaring. Outside module
declarations, current class is set to the eigenclass of self.

I hope this is not a complete mess and rubbish :slight_smile:

TPR.

···

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

Thomas, thanks for your reply.

So I guess the general rule is: inside module declaration, both self and
current class are set to the module we're declaring. Outside module
declarations, current class is set to the eigenclass of self.

I hope this is not a complete mess and rubbish :slight_smile:

Consider this case:

  class SomeClass
    # self is SomeClass, current class is SomeClass
    puts "Class Level - #{self}"

    def some_method
      # self is an instance, current class is SomeClass
      puts "Some Method - #{self}"

      def self.some_inside_class_method
        # self is an instance, current class is instance's singleton
class
        puts "Inside class method - #{self}"
      end

      def some_inside_instance_method
        # self is an instance, current class is SomeClass
        puts "Inside instance method - #{self}"
      end

      # self is an instance, current class is instance's singleton class
      instance_eval { puts "Instance instance_eval - #{self}" }
      # no class_eval for instances
    end

    def self.class_method
      # self is SomeClass, current class is SomeClass's singleton class
      puts "Class method - #{self}"
    end

    # self is SomeClass, current class is SomeClass's singleton class
    instance_eval { puts "Class instance_eval - #{self}" }

    # self is SomeClass, current class is SomeClass
    class_eval { puts "Class class_eval - #{self}" }
  end

Are all the comments correct about self and current class value and are
all cases covered (current class modification)?
Is def the only method that uses the current class value?
I used Class but Module has the same behaviour.

Pedro.

···

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

Hi --

Pedro Silva wrote:

I know that Ruby always keeps track of two concepts: self and current
class.

The programmer only can access the first one, that tracks the current
object. I know that self is the default receiver when invoking methods
and that obviously affects the way Ruby processes the code. Fortunately
self I understand quite well.

My doubt comes with the current class concept. I know that when we use
instance_eval, self is set to the receiver and current class to the
singleton class, that's why it allows to define singleton methods. I
would like to undestand how current class is altered by Ruby because
there's no way to print stuff and see what happens.

Can anyone enumerate which cases Ruby uses current class and a general
rule for current class status?

Pedro.

Hello.

Well, at first I thought that you can always check the current class
using
class<<self;self;end
but now I see I was wrong. Good I realised it before posting.

In fact, most of the time this is the way to check the current class.

I don't think so. Most of the time you're likely to be inside a method
definition body, where the singleton class is not relevant unless you
invoke it more or less explicitly.

Inside x.instance_eval{} self is set to x, and the current class is set
to class<<x;self;end (that is, x's eigenclass), so when you def a method
there, it will become a method of x (you will be able to call it by
x.method, no matter if x is a regular object or a class), and the class
that will hold the method is the x's eigenclass - it will be visible in
class<<x;instance_methods;end.

But there is an exception from this rule. Inside class declaration:
class K
#here
end
self is set to the class (that is, K), class<<self;self;end is of course
the class'es eigenclass, but if you def a method now, it will not become
the method that you can call by K.method, but it will become an instance
method of the class K, and that means that K was the current class at
the time of declaring the method, even though it was self at the same
time.

I think you're over-complicating this by using instance_eval as your
starting point and then describing the behavior of class definitions
as an exception to a rule. Most of the purpose of class definition
blocks is to define instance methods, so it's easier just to look at
it that way directly. If anything, I'd look at instance_eval as having
the exceptional behavior -- but really, there are so few different
permutations that it's probably easiest just to learn them and not
worry about which is the rule and which the exception.

The only really weird one is the top level :slight_smile:

David

···

On Tue, 2 Sep 2008, Thomas B. 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!

Hi --

Thomas, thanks for your reply.

So I guess the general rule is: inside module declaration, both self and
current class are set to the module we're declaring. Outside module
declarations, current class is set to the eigenclass of self.

I hope this is not a complete mess and rubbish :slight_smile:

Consider this case:

class SomeClass
   # self is SomeClass, current class is SomeClass
   puts "Class Level - #{self}"

   def some_method
     # self is an instance, current class is SomeClass
     puts "Some Method - #{self}"

     def self.some_inside_class_method
       # self is an instance, current class is instance's singleton
class
       puts "Inside class method - #{self}"

That's not a class method. self is an instance of SomeClass; you're
defining a singleton method on that instance. Every time you do:

   def obj.something

you're defining a singleton method "something" on obj. self is just an
alias for a particular object at a particular point in runtime.

     end

     def some_inside_instance_method
       # self is an instance, current class is SomeClass
       puts "Inside instance method - #{self}"
     end

I'm not sure what you mean by "inside" in the method name. It's just
an instance method.

     # self is an instance, current class is instance's singleton class
     instance_eval { puts "Instance instance_eval - #{self}" }
     # no class_eval for instances
   end

   def self.class_method
     # self is SomeClass, current class is SomeClass's singleton class
     puts "Class method - #{self}"
   end

   # self is SomeClass, current class is SomeClass's singleton class
   instance_eval { puts "Class instance_eval - #{self}" }

   # self is SomeClass, current class is SomeClass
   class_eval { puts "Class class_eval - #{self}" }
end

Are all the comments correct about self and current class value and are
all cases covered (current class modification)?
Is def the only method that uses the current class value?

It's a keyword, rather than a method, but I think it is the only thing
that cares about the notion of "current class", at least as I
understand that notion. (I admit it's not one that I've paid much
attention to, by that name, though of course I like to know what 'def'
will do at any given time.)

David

···

On Tue, 2 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!

Hi there.

For me, your diagram is perfectly correct (however I had some doubts at
the beginning again).

Well, I wouldn't say that now all cases are covered, even though it
looks like they are. But the diagram is not good for framing and putting
on the wall, it is only good for learning from it. Because there are
special cases like:

class<<nil;self;end #=> NilClass
class<<true;self;end #=> TrueClass

This kind of primitives appears not to have eigenclass at all, but there
is only one instance of each of the NilClass, FalseClass and TrueClass,
so it's not a problem. Still methods can be added to these primitives.

class<<5;end # raises TypeError: no virtual class for Fixnum

This primitive doesn't have eigenclass at all, you cannot add methods to
one particular instance of Fixnum. You cannot even _be_ inside this
nonexistent singleton class.

Also, have a look at this case:

eval("def q;end",nil.instance_eval{binding})

It raises an error. There's a place (inside the eval), where you _can_
be, but cannot define a method. So I guess juggling with bindings can
produce some more cases.

Is def the only method that uses the current class value?

I suppose yes (probably alias also). But in fact it's not a method, not
even a private one. It must be something else, that cannot be hacked
easily (oh no, are there such things in Ruby?).

I must say I definitely learnt something from your question.

TPR

···

--

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

David A. Black wrote:

In fact, most of the time this is the way to check the current class.

I don't think so. Most of the time you're likely to be inside a method
definition body, where the singleton class is not relevant unless you
invoke it more or less explicitly.

You're right. That was my sort of inaccurate concept.

I think you're over-complicating this by using instance_eval as your
starting point and then describing the behavior of class definitions
as an exception to a rule. Most of the purpose of class definition
blocks is to define instance methods, so it's easier just to look at
it that way directly. If anything, I'd look at instance_eval as having
the exceptional behavior -- but really, there are so few different
permutations that it's probably easiest just to learn them and not
worry about which is the rule and which the exception.

Here I can't fully agree, as I showed it in the previous post there are
some more cases, not all of which equally obvious. But it's true that
you can call a rule and an exception whichever case you want, for me
it's more natural to think that I'm inside instance_eval, because then
I'm adding methods to an already existing instance, and not to all the
instances potentially existing in the future.

The only really weird one is the top level :slight_smile:

There's no top level in fact. In the top level, you're inside some
instance of Object, you're

class<<Object::new
  # here.
end

or

Object::new.instance_eval{
#here
}

or, even more precisely,

eval("#here.",Object::new.instance_eval{binding})

So when you def a method, it goes just to this sole instance. Also the
method to_s of this object is changed to display "main", and in irb some
irb-specific methods are added to the instance.

TPR

···

--

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

Hi David,

def self.some_inside_class_method
  puts "Inside class method - #{self}"
end

That's not a class method. self is an instance of SomeClass; you're
defining a singleton method on that instance.

If forgot to change the text, I mean't singleton method. Thanks for
pointing that out.

     def some_inside_instance_method
       # self is an instance, current class is SomeClass
       puts "Inside instance method - #{self}"
     end

I'm not sure what you mean by "inside" in the method name. It's just
an instance method.

This case was to test the def keyword inside an instance method, because
at class level self is the class, inside instance method self is the
instance.

It's a keyword, rather than a method, but I think it is the only thing
that cares about the notion of "current class", at least as I
understand that notion. (I admit it's not one that I've paid much
attention to, by that name, though of course I like to know what 'def'
will do at any given time.)

I really wanted to know if current class is used anywhere else by any
other keyword/method to try to fully understand these two concepts.

Pedro.

···

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

Hi --

···

On Tue, 2 Sep 2008, Thomas B. wrote:

Is def the only method that uses the current class value?

I suppose yes (probably alias also). But in fact it's not a method, not
even a private one. It must be something else, that cannot be hacked
easily (oh no, are there such things in Ruby?).

It's a keyword.

David

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

Thomas B. wrote:

eval("#here.",Object::new.instance_eval{binding})

So when you def a method, it goes just to this sole instance.

$ cat foo.rb
def foo
   puts "FOO"
end

class A
   def bar
     foo
   end
end

A.new.bar

$ ruby foo.rb
FOO

···

--
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407