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 ofClass
, how can it be both a superclass ofClass
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 alwaysObject
. [Note: there may be implementation-defined superclasses ofObject
, but eventually, there will be one which doesn't have a superclass.]Object
is an instance ofClass
, which is a subclass ofObject
(which means that indirectlyObject
is an instance ofObject
itself)Class
is a subclass ofModule
, which is an instance ofClass
Class
is an instance ofClass
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
, andBasic Object
are instances ofClass
is not becauseClass < Module < Object < BasicObject
. It has nothing to do with it. - (3.)
(Object.new).instance_of? Class
returnsfalse
not becauseObject.new
is an instance ofObject
. It is because it is not an instance ofClass
. Class.is_a? Object
istrue
not because [the mentioned]Class
is a subclass ofObject
. It is because (the mentioned)Class
is an instance ofClass
(which is not mentioned), which is a subclass ofObject
.
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
- 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? - 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?
- 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 ofNode
would be in one node scope includingdisplay
. You implementedNode.display()
to display the whole linked list and therefor you "don't need" aLinkedList
class. I think it is better to add aLinkedList
class with ahead
variable to hold the first node and adisplay
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
In Ruby's Test::Unit::Testcase, How to Override the Initialize Method
How to Pass a Parameter for Gem Installation When I Run Bundle Install
Rails on Windows Is So Slow (Rails -V Takes 4 Seconds)
Rails Forms for Has_Many Through Association with Additional Attributes
Getting an Ascii Character Code in Ruby Using '' (Question Mark) Fails
How to Uninstall Ruby from /Usr/Local
How to Url Encode a String in Ruby
Trying to Set Up Postgres for Ror App, Getting Error - Fe_Sendauth: No Password Supplied
Devise - How to Change Setting So That Email Addresses Don't Need to Be Unique
Combination of Two Arrays in Ruby
How to Pass Multiple Arguments to a Ruby Method as an Array
What Does 'If _File_ == $0' Mean in Ruby
Sorting a Ruby Array of Objects by an Attribute That Could Be Nil
Encoding::Undefinedconversionerror
Installing Ruby on MAC Os X 10.8.2
How to Add Information to an Exception Message in Ruby
Openssl::Ssl::Sslerror: Ssl_Connect Returned=1 Errno=0 State=Unknown State: Unknown Protocol