How to find the wrapped class name of a singleton class? - ruby

Given a self as below, how to find its class name:
self = #<Class:#<PaymentRequestx::PaymentRequest:0x0000000b2a3400>>
What I am looking for is to return PaymentRequestx::PaymentRequest. self.name (nil) and self.class.name (Class) do not return the right answer. Here is more info about the self:
How can I retrieve PaymentRequestx::PaymentRequest?

If you want to get the only instance of a singleton class, you can find it in ObjectSpace.
some_singleton_class = some_obj.singleton_class
some_obj_2 = ObjectSpace.each_object(some_singleton_class).first
some_obj_2.object_id == some_obj.object_id #=> true
If your self is a class's singleton class, then the class you're searching for is the only instance of that singleton class.
ObjectSpace.each_object(self).first.name #=> should return "PaymentRequestx::PaymentRequest"
This approach may not be fast so avoid using it whenever possible.
WARNING: If the class you want has subclasses, then this approach will not work. For example
ObjectSpace.each_object(Object.singleton_class).to_a
will return a huge amount of classes (think why).
UPDATE
You can do further filter from the search result from ObjectSpace.
def instance_of(singleton_class)
ObjectSpace.each_object(singleton_class).find do |obj|
obj.singleton_class == singleton_class
end
end
instance_of(Object.singleton_class) #=> Object

Inspection of the form:
#<Class:#<SomeModule>>
indicates the singleton class of SomeModule. When SomeModule is actually an anonymous instance of a module, it looks like this:
a = Module.new
# => #<Module:0x007f6f86eb8fa0>
a.singleton_class
# => #<Class:#<Module:0x007f6f86eb8fa0>>
You have an anonymous class that is the singleton class of an anonymous instance 0x0000000b2a3400 of PaymentRequestx::PaymentRequest, which must be a module. You cannot name a singleton class, so you cannot get its name.
On getting the original module of a singleton class, follow an answer provided here.

Try self.ancestors.first.name
:ancestors returns a list of modules prepended or included to whatever it's called on.

Related

Ruby’s secret trick to avoid “class methods” and keep its type system simple and elegant

From Wikibooks' Ruby Programming/Overview:
When I said that every Ruby object has a class, I lied. The truth is, every object has two classes: a “regular” class and a singleton class. An object’s singleton class is a nameless class whose only instance is that object. Every object has its very own singleton class, created automatically along with the object. Singleton classes inherit from their object’s regular class and are initially empty, but you can open them up and add methods to them, which can then be called on the lone object belonging to them. This is Ruby’s secret trick to avoid “class methods” and keep its type system simple and elegant
The above passage says that Ruby's secret trick to avoid class methods. I don't understand what the author means here. Where is Ruby stopping us to avoid class methods? for an example, look at the example shown below
class Raj
def self.hi
puts 'Hi'
end
def hello
puts 'hello'
end
end
object=Raj.new
object.hello
Raj.hi
As you can see in the preceding example, the class methods can still be created.
yes?
I understand that there are no true class methods in Ruby; instead, they are methods that are created for the Raj object.
But, in any case, it's allowing me to create the method 'hi,' right?
So, what does it mean when it says, 'This is Ruby's secret trick for avoiding "class methods" and keeping its type system simple and elegant'?
I understand that there are no true class methods in Ruby; instead, they are methods that are created for the Raj object.
That's exactly it, though.
def self.hi
puts 'Hi'
end
This is not a class method or static method. Those don't exist in Ruby. That's the whole point. Your class Raj defines an object of type Class. We can see its type with the #class function.
> Raj.class
=> Class
We can also see its ancestors.
> Raj.class.ancestors
=> [Class, Module, Object, PP::ObjectMixin, Kernel, BasicObject]
Class inherits from Module, since (for the most part) classes can do everything modules can. Module, in turn, inherits from Object, which has some modules of its own mixed in (PP:ObjectMixin is for pretty-printing, and Kernel gets you the nice helpers like puts) and eventually inherits from the root class BasicObject.
But this isn't the whole story, for Raj has its own class as well: its singleton class. We can see the full story by calling #singleton_class instead of #class.
> Raj.singleton_class.ancestors
=>
[#<Class:Raj>,
#<Class:Object>,
#<Class:BasicObject>,
Class,
Module,
Object,
PP::ObjectMixin,
Kernel,
BasicObject]
Now there's a lot more going on. Raj is an instance of the singleton class of Raj, which inherits from the singleton class of Object, which in turn inherits from the singleton class of BasicObject, which inherits from Class and all of the stuff we saw before.
So when you define a method on the class Raj, you're defining it (as an instance method) on the singleton class #<Class:Raj>. And that class (currently) has one instance: Raj.
By the way, it's also useful to know that the term "singleton class" is a bit of a lie. As you can see, the class is very much not a singleton in general. For instance, the singleton class of Object, called #<Class:Object> above, actually has several instances: Object, Raj, String, and most Ruby classes. Personally, I prefer to call them eigenclasses for that reason, but "singleton class" is the official (and more well-known) term.
The author is talking about the singleton class in this sentence, there is a really nice article to deep dive into ruby singleton class: https://medium.com/#leo_hetsch/demystifying-singleton-classes-in-ruby-caf3fa4c9d91
Here is a nice example extracted from this article:
class Vehicle
def initialize(kms)
#kms = kms
end
def drive
puts "let's go!"
end
end
car = Vehicle.new(1000)
bus = Vehicle.new(3000)
def car.drive
print "I'm driving a car! "
super
end
car.drive # "I'm driving a car! let's go!"
bus.drive # "let's go!"
As you can see, here the #drive method has been overridden but only for the car object, the bus object is still using the #drive method defined in the Vehicle class.
This new method is defined on the singleton class (or shadow class) of the object, this is allowing you to define new methods on the fly on an object without polluting all the objects of this class.
This means that Ruby doesn't implement class methods.
Indeed, the Ruby OBJECT Model, allows you to "emulate" the definition of class methods by defining instance methods on the Eigenclass:
class Greeting
def self.hello
'hello world!'
end
def self.eigenclass
class << self
self
end
end
end
Greeting.eigenclass # => #<Class:Greeting>
Greeting.eigenclass.name # => nil
Greeting.singleton_methods # => [:hello, :eigenclass]
Greeting.eigenclass.instance_methods(false) # => [:hello, :eigenclass]
First, we define a Greeting.eigenclass method. This method returns self in the context of the eigenclass — by using the class << self ... end syntax. In this case, self contains an unnamed instance of the class Class (a.k.a an anonymous class). This anonymous class keeps track of the class to which it is attached — the Greeting class in our case.
Then, we can see that the singleton methods of the Greeting class are the instance methods of the Greeting eigenclass.
Feel free to have a look to this very detailed article to learn more about this concept.
To illustrate #Sébastien P.'s answer:
dice = [1,2,3,4,5,6] #an ordinary array instance
def dice.throw #now it has an extra
sample
end
p dice.throw #=>3

Location of public class method 'new' of 'Class'

Ruby's Class class lists two methods named 'new':
Class::new is a public class method
Class#new is a public instance method
But when I do:
Class.methods(false)
#=> []
which is supposed to list singleton methods (which I am assuming what class methods are), I get an empty array. Why is this so? Where is Class::new defined?
The methods shown as ::new in the documentation are usually #initialize, for example Range::new:
new(begin, end, exclude_end=false) → rng
Constructs a range using the given begin and end. If the exclude_end parameter is omitted or is false, the rng will include the end object; otherwise, it will be excluded.
This is because you create instances via:
r = Range.new(0, 2) #=> 0..2
Rather than:
r = Range.allocate #=> nil..nil
r.send(:initialize, 0, 2) #=> nil
r #=> 0..2
That's exactly what ::new does – it creates a new instance via allocate, sends it initialize (passing arguments) and returns the instance.
The actual new method is inherited from Class (since Range is an instance of Class) – Class#new:
new(args, ...) → obj
Calls allocate to create a new object of class’s class, then invokes that object’s initialize method, passing it args. This is the method that ends up getting called whenever an object is constructed using .new.
Just like allocate, inherited and superclass (and the instance methods from Class' ancestors like Module as well):
Range.method(:new)
#=> #<Method: Class#new>
Range.method(:allocate)
#=> #<Method: Class#allocate>
Range.method(:ancestors)
#=> #<Method: Class(Module)#ancestors>
So if you call Class.new:
my_string_class = Class.new(String)
#=> #<Class:0x007fdf5485b200>
you just invoke Class#new which is (again) equivalent to:
my_string_class = Class.allocate
my_string_class.send(:initialize, String)
my_string_class
#=> #<Class:0x007fdf5484beb8>
One notable exception is Struct which in fact provide its own new class method:
Struct.method(:new)
#=> #<Method: Struct.new>
Unlike other classes, Struct::new does not return instances of Struct but instances of Class (which are subclasses of Struct).
tl;dr summary:
Why is this so?
Because it's not a singleton method.
Where is Class::new defined?
It isn't. The call Class.new is just calling Class#new (since Class is an instance of itself). The documentation for Foo::new is actually the documentation for Foo#initialize for any class Foo, including Class itself.
If you want to know something about Ruby, it is often a good idea to ask her herself:
new_method = Class.method(:new)
#=> #<Method: Class#new (defined in Class at core/alpha.rb:90)>
The Object#method method returns a Method object representing the method. (Methods aren't objects in Ruby themselves, but you can get a reflective proxy object that represents a method.)
You can ask a Method where it is defined using the Method#owner method:
new_method.owner
#=> Class
As you can see, new is defined in Class and not in Class's singleton class.
You can also ask a Method about the location of its Ruby source code using the Method#source_location method:
new_method.source_location
#=> ['core/alpha.rb', 90]
What this tells us is that Class#new is defined in the file core/alpha.rb on line 90:
def new(*args)
obj = allocate()
Rubinius.asm(args, obj) do |args, obj|
run obj
run args
push_block
send_with_splat :initialize, 0, true
# no pop here, as .asm blocks imply a pop as they're not
# allowed to leak a stack value
end
obj
end
The method is partially implemented in bytecode for performance reasons, but it is basically just:
class Class
def new(*args, &block)
obj = allocate
obj.__send__(:initialize, *args, &block) # because initialize is private
#obj.initialize(*args, &block)
obj
end
end
Now, you might ask yourself: why is there an entry for Class::new in the RDoc documentation, if that method doesn't exist? Well, RDoc knows about the relationship between #initialize which is the method you define but usually don't call directly and Class#new which is the method you call but usually don't define, and it will document #initialize as ::new if it exists.
So, what we really want to look at, is Class#initialize:
initialize_method = Class.method(:initialize)
#=> #<Method: Class#initialize (defined in Class at core/class.rb:15)>
initialize_method.owner
#=> Class
initialize_method.source_location
#=> ['core/class.rb', 15]
This is the source:
def initialize(sclass=Object, name=nil, under=nil)
raise TypeError, "already initialized class" if #instance_type
raise TypeError, "can't make subclass of Class" if Class.equal?(sclass)
set_superclass sclass
# Things (rails) depend on the fact that a normal class is in the constant
# table and have a name BEFORE inherited is run.
under.const_set name, self if under
if sclass
Rubinius.privately do
sclass.inherited self
end
end
super()
end
private :initialize
Class#initialize essentially does three things:
set the superclass
optionally assign the class to a constant to give it a name
call the Class#inherited hook method of the superclass
If you want to know what the relationships between some of the core classes that magically spring into existence at the beginning are, you can take a look at the initialization code of some Ruby execution engines, e.g.
Rubinius: VM::bootstrap_class in machine/ontology.cpp
JRuby: org.jruby.Ruby.initRoot in core/src/main/java/org/jruby/Ruby.java
IronRuby: the initial classes are generated by a program, the generator is in the directory Src/ClassInitGenerator
MRuby: mrb_init_class in src/class.c
Note: depending on what Ruby implementation you use, obviously the places where those methods are defined and how exactly they are defined may vary.
new is defined as a instance method of Class class, rather than a singleton method:
Class.instance_method :new # => #<UnboundMethod: Class#new>
Tricky to note: Class (object) itself is also an instance of Class (class).
Class.instance_of? Class # => true

What is `singleton_class` method in class and object?

I defined methods specific_data1 and specific_data2 in meta class, and expected these methods belong to the singleton class:
class User
def User.specific_data1
"user specific data defined on user"
end
class << self
def specific_data2
"user specific data defined in meta class"
end
end
end
But neither of the methods is found in:
User.singleton_class.methods
Please help me understand what singleton_method on User class is and how it is useful.
Object#methods returns the methods of that object. Methods defined in a class aren't methods of that class object, they are methods of that class's instances.
This has nothing to do with singleton classes, it's true for all classes:
class Foo
def bar; end
end
Foo.methods.include?(:bar)
# => false
Foo.new.methods.include?(:bar)
# => true
Foo.instance_methods
# => [:bar]
Here's how that works with your example:
User.methods.grep(/specific/)
# => [:specific_data1, :specific_data2]
User.singleton_methods
# => [:specific_data1, :specific_data2]
User.singleton_class.instance_methods.grep(/specific/)
# => [:specific_data1, :specific_data2]
Both of the methods you defined are defined as instance methods on the singleton_class.
User.singleton_class.instance_methods(false)
# => [:specific_data1, :specific_data2]
Jorg got the technical part of your question right. You want to check
User.singleton_class.instance_methods
As for this
Please help me understand what singleton_method on User class is and how it is useful."
Suppose you have an object x and you want to define a method for it. One way would be to define the method in x's class, but this has the side effect of defining the method for all other objects of that class! What if you just want to define the method for the single object x?
Ruby solves this problem by letting you create a class which has only a single instance: x. This is the singleton class. Methods defined in it will only affect x because the singleton class is a subclass of x.class and its only instance is x. Singleton methods are just regular methods defined in a singleton class.

Get Ruby class name without class method

How can I get the class name of an instance of BasicObject in Ruby? For example, say I have this:
class MyObjectSystem < BasicObject
end
puts MyObjectSystem.new.class
How can I make this code succeed?
EDIT: I've found that Object's instance method class is defined as return rb_class_real(CLASS_OF(obj));. Any way to use this from Ruby?
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.
I have to leave in a few minutes so I can't test it myself, but it seems like you could make a separate module that uses ffi to call rb_class_real from libruby. If I had more time I would test it first, but nobody else has answered yet and I don't want you leave you totally out in the cold.
Based on Jeff Smith's answer, you can do this without modifying BasicObject:
class << object; self; end.superclass
where object is an instance of an object whose class you want, i.e.,
irb(main):001:0> object = BasicObject.new
(Object doesn't support #inspect)
=>
irb(main):002:0> class << object; self; end.superclass
=> BasicObject

Ruby metaclass madness

I'm stuck. I'm trying to dynamically define a class method and I can't wrap my head around the ruby metaclass model. Consider the following class:
class Example
def self.meta; (class << self; self; end); end
def self.class_instance; self; end
end
Example.class_instance.class # => Class
Example.meta.class # => Class
Example.class_instance == Example # => true
Example.class_instance == Example.meta # => false
Obviously both methods return an instance of Class. But these two instances
are not the same. They also have different ancestors:
Example.meta.ancestors # => [Class, Module, Object, Kernel]
Example.class_instance.ancestors # => [Example, Object, Kernel]
What's the point in making a difference between the metaclass and the class instance?
I figured out, that I can send :define_method to the metaclass to dynamically define a method, but if I try to send it to the class instance it won't work. At least I could solve my problem, but I still want to understand why it is working this way.
Update Mar 15, 2010 13:40
Are the following assumptions correct.
If I have an instance method which calls self.instance_eval and defines a method, it will only affect the particular instance of that class.
If I have an instance method which calls self.class.instance_eval (which would be the same as calling class_eval) and defines a method it will affect all instances of that particular class resulting in a new instance method.
If I have a class method which calls instance_eval and defines a method it will result in a new instance method for all instances.
If I have a class method which calls instance_eval on the meta/eigen class and defines a method it will result in a class method.
I think it starts to make sense to me. It would certainly limit your possibilities if self inside an class method would point to the eigen class. If so it would not be possible to define an instance method from inside a class method. Is that correct?
Defining a singleton method dynamically is simple when you use instance_eval:
Example.instance_eval{ def square(n); n*n; end }
Example.square(2) #=> 4
# you can pass instance_eval a string as well.
Example.instance_eval "def multiply(x,y); x*y; end"
Example.multiply(3,9) #=> 27
As for the difference above, you are confusing 2 things:
The meta class defined by you, is what called in Ruby community as singelton class or eigen class. That singleton class is the class that you can add class(singleton) methods to.
As for the class instance you are trying to define using the class_instance method, is nothing but the class itself, to prove it, just try adding an instance method to the class Example and check if the class_instance method defined by you returns the class Example itself by checking the existence of that method:
class Example
def self.meta; (class << self; self; end); end
def self.class_instance; self; end
def hey; puts hey; end
end
Example.class_instance.instance_methods(false) #=> ['hey']
Anyway to sum it for you, when you want to add class methods, just add them to that meta class. As for the class_instance method is useless, just remove it.
Anyway I suggest you read this post to grasp some concepts of Ruby reflection system.
UPDATE
I suggest you read this nice post: Fun with Ruby's instance_eval and class_eval,
Unfortunately class_eval and instance_eval are confusing because they somehow work against their naming!
Use ClassName.instance_eval to define class methods.
Use ClassName.class_eval to define instance methods.
Now answering your assumptions:
If I have an instance method which
calls self.instance_eval and defines a
method, it will only affect the
particular instance of that class.
yes:
class Foo
def assumption1()
self.instance_eval("def test_assumption_1; puts 'works'; end")
end
end
f1 = Foo.new
f1.assumption1
f1.methods(false) #=> ["test_assumption_1"]
f2 = Foo.new.methods(false) #=> []
If I have an instance method which
calls self.class.instance_eval (which
would be the same as calling
class_eval) and defines a method it
will affect all instances of that
particular class resulting in a new
instance method.
no instance_eval in that context will define singleton methods(not instance ones) on the class itself:
class Foo
def assumption2()
self.class.instance_eval("def test_assumption_2; puts 'works'; end")
end
end
f3 = Foo.new
f3.assumption2
f3.methods(false) #=> []
Foo.singleton_methods(false) #=> ["test_assumption_2"]
For that to work replace instance_eval with class_eval above.
If I have a class method which calls
instance_eval and defines a method it
will result in a new instance method
for all instances.
Nope:
class Foo
instance_eval do
def assumption3()
puts 'works'
end
end
end
Foo.instance_methods(false) #=> []
Foo.singleton_methods(false) #=> ["assumption_3"]
That will make singleton methods, not instance methods. For that to work replace instance_eval with class_eval above.
If I have a class method which calls
instance_eval on the meta/eigen class
and defines a method it will result in
a class method.
well no, that will make so sophisticated stuff, as it will add singleton method to the singleton class, I don't think that will have any practical use.
If you define a method on a class, it can be invoked on its objects. It is an instance method.
class Example
end
Example.send :define_method, :foo do
puts "foo"
end
Example.new.foo
#=> "foo"
If you define a method on a metaclass, it can be invoked on the class. This is similar to the concept of a class method or static method in other languages.
class Example
def self.metaclass
class << self
self
end
end
end
Example.metaclass.send :define_method, :bar do
puts "bar"
end
Example.bar
#=> "bar"
The reason that metaclasses exist is because you can do this in Ruby:
str = "hello"
class << str
def output
puts self
end
end
str.output
#=> "hello"
"hi".output
# NoMethodError
As you can see, we defined a method that is only available to one instance of a String. The thing that we defined this method on is called the metaclass. In the method lookup chain, the metaclass is accessed first before searching the object's class.
If we replace the object of type String with an object of type Class, you can imagine why this means we're only defining a method on a specific class, not on all classes.
The differences between the current context and self are subtle, you can read more if you're interested.

Resources