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.

Pedro S. 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.

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.

Hi –

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

instance_eval, self is set to the receiver and current class to the

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.

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

Hi –

On Tue, 2 Sep 2008, Pedro S. wrote:

class SomeClass
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 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

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.

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

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

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

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