How to Get the Class of a Basicobject Instance

How do I get the class of a BasicObject instance?

If you can upgrade to Ruby 2.0, you don't need to implement anything at all:

>> Kernel.instance_method(:class).bind(BasicObject.new).call
=> BasicObject

Why is EVERYTHING an instance of Class in Ruby?

First, is EVERYTHING in Ruby an instance of Class?

No, not everything is an instance of Class. Only classes are instances of Class.

There are lots of things which aren't instances of Class: strings, for example, are instances of String, not Class. Arrays are instances of Array, integers are instances of Integer, floats are instances of Float, true is an instance of TrueClass, false is an instance of FalseClass, nil is an instance of NilClass, and so on.

Every class is an instance of Class, just like every string is an instance of String.

if Object is a superclass of Class, how can it be both a superclass of Class and an instance of it at the same time (most diagrams on the Ruby Object Model clearly state this hierarchy)?

Magic.

Just like in most other languages, there are some core entities that are simply assumed to exist. They fall from the sky, materialize out of thin air, magically appear.

In Ruby, some of those magic things are:

  • Object doesn't have a superclass, but you cannot define a class with no superclass, the implicit direct superclass is always Object. [Note: there may be implementation-defined superclasses of Object, but eventually, there will be one which doesn't have a superclass.]
  • Object is an instance of Class, which is a subclass of Object (which means that indirectly Object is an instance of Object itself)
  • Class is a subclass of Module, which is an instance of Class
  • Class is an instance of Class

None of these things can be explained in Ruby.

BasicObject, Object, Module and Class all need to spring into existence at the same time because they have circular dependencies.

Just because this relationship cannot be expressed in Ruby code, doesn't mean the Ruby Language Specification can't say it has to be so. It's up to the implementor to figure out a way to do this. After all, the Ruby implementation has a level of access to the objects that you as a programmer don't have.

For example, the Ruby implementation could first create BasicObject, setting both its superclass pointer and its class pointer to null.

Then, it creates Object, setting its superclass pointer to BasicObject and its class pointer to null.

Next, it creates Module, setting its superclass pointer to Object and its class pointer to null.

Lastly, it creates Class, setting its superclass pointer to Module and its class pointer to null.

Now, we can overwrite BasicObject's, Object's, Module's, and Class's class pointer to point to Class, and we're done.

This is easy to do from outside the system, it just looks weird from the inside.

Ruby: is_a? and instance_of? in BasicObject

You can steal is_a? from Kernel:

class My < BasicObject
define_method(:is_a?, ::Kernel.method(:is_a?))
end

m = My.new
m.is_a?(My) #=> true
m.is_a?(BasicObject) #=> true
m.is_a?(Object) #=> false

If you're going to build your own object hierarchy, you could also define your own Kernel, something like:

module MyKernel
[:is_a?, :instance_of?, :class].each do |m|
define_method(m, ::Kernel.method(m))
end
end

class My < BasicObject
include ::MyKernel
end

Get Ruby class name without class method

I spent some time playing around with irb and came up with this:

class BasicObject
def class
klass = class << self; self; end # get the object's singleton class
klass.superclass # the superclass of an object's singleton class is that object's class
end
end

That will give any object that inherits from BasicObject a #class method that you can call.

Edit

Further explanation as requested in the comments:

Say you have object obj that is an instance of class Foo. obj gets its instance methods from those that are defined within the class Foo, in addition to the methods defined in Foo's parent class and so on up the inheritance chain. Ruby lets you define methods directly on an object that are only accessible to that particular object like this

obj = Foo.new
def obj.hello
puts "hello"
end

obj.hello #=> hello

other_obj = Foo.new
other_obj.hello #=> Method missing error

The reason you can do this is because every object has something called a singleton class (or sometimes call an eigenclass) that you are actually defining the method on. This singleton class actually exists in the inheritance chain of the object directly beneath the object's actual class. That makes the object's actual class, Foo in this example, the superclass of the object's singleton class.

The class << self line you see in the answer is a special syntax for entering the scope of an object's singleton class. So in the example above, you could also define a method in an object's singleton class like this

class << obj
def goodbye
puts "goodbye"
end
end

obj.goodbye #=> goodbye

So the line class << self; self; end is opening the object's singleton class (whatever object is currently self) and then returning self (self has now become the singleton class), which can then be assigned to a variable to do what you wish with.

I would recommend reading Metaprogramming Ruby if you want a better explanation of all this. It definitely gives you a much better understanding of the Ruby object model as a whole.

Ruby's Classes and Objects

You have several things wrong.

  • (2.) The reason Class, Module, Object, and Basic Object are instances of Class is not because Class < Module < Object < BasicObject. It has nothing to do with it.
  • (3.) (Object.new).instance_of? Class returns false not because Object.new is an instance of Object. It is because it is not an instance of Class.
  • Class.is_a? Object is true not because [the mentioned] Class is a subclass of Object. It is because (the mentioned) Class is an instance of Class (which is not mentioned), which is a subclass of Object.

The answer to the question is: Object.is_a? Class returns true because Object is an instance of Class.

If you want to know the class of an instance, use instance_of? or class methods.

3.is_a?(Object) # => false
3.is_a?(Fixnum) # => true
3.class # => Fixnum

Basic object oriented implementation in python

  1. The variables outside the __init__ method are called class variables and inside the method are called instance variables. This will answer your question: What is the difference between class and instance variables?
  2. In python, all variables are public so you don't need getter setter methods unless you want them in order to protect the variable value or you want to process / validate the value before setting / getting the variable. More is here: What's the pythonic way to use getters and setters?
  3. There is a design flaw in your code. The class Node represents one node. So, if I had to use this implementation I would expect all methods of Node would be in one node scope including display. You implemented Node.display() to display the whole linked list and therefor you "don't need" a LinkedList class. I think it is better to add a LinkedList class with a head variable to hold the first node and a display method just like you wrote to make it more intuitive.

How to get current instance in class?

Self is the current instance of all the class. In your case,

class Basic(object):
def __init__(self, val):
self.val = val

def current_ins(self):
#???
print self.val # one can use self to access all the member of it's class.


Related Topics



Leave a reply



Submit