Inheritance of constructors in Ruby - ruby

Lets say I create a new class which inherits from Symbol. Symbols are unique and it is very clear that the Symbol class has no Constructor. But which mechanism prevents the creation of a constructor in the child class? Is there some flag which makes all children unique?
class Syb < Symbol
def initialize
end
end
p Syb.respond_to? :new
false

First of all I also believe that is not a good idea to extend ruby core classes, references
In this case in particular
"For efficiency, many core class methods are coded in C instead of Ruby. And in some cases, such as this Array addition operator, they are implemented in such a way that the class of the return value is hardcoded."
If you take a look of the initialize method in the ruby Symbol class (it really has):
[36] pry(main)> require 'pry-doc'
=> true
[72] pry(main)> cd Symbol
[73] pry(Symbol):1> $ initialize
From: object.c (C Method):
Owner: BasicObject
Visibility: private
Signature: initialize()
Number of lines: 5
static VALUE
rb_obj_dummy0(VALUE _)
{
return rb_obj_dummy();
}
So we can see that this method allready exists and it is implemented in c, but there is a limitation about overiding ruby core classes methods, explained in this answer
And I also believe that is really important to investigate ruby with, pry pry-doc and pry-gem

As Sergio stated, my mistake was the mix up of constructor and initializer. Actually it is possible to write a new constructor for the Symbol class.
irb(main):001:1* class Symbol
irb(main):002:2* def Symbol.new x
irb(main):003:2* x.to_sym
irb(main):004:1* end
irb(main):005:0> end
=> :new
irb(main):008:0> a = Symbol.new "xyz"
=> :xyz
irb(main):009:0> a
=> :xyz
Yes I realize that here the symbol is actually created by the .to_sym method. So new is not really a constructor but more like a wrapper for the real constructor.

Lets say I create a new class which inherits from Symbol. Symbols are unique and it is very clear that the Symbol class has no Constructor.
This statement is trivially true, since Ruby has no constructors.
But which mechanism prevents the creation of a constructor in the child class?
The fact that Ruby has no constructors prevents the creation of a constructor.
Is there some flag which makes all children unique?
No.

Related

Ruby's Classes and Objects

I've been reading a lot about ruby classes vs objects and I came to this conclusion
There is a concept called "class" and we have the following classes:
BasicObject
which is the superclass of
Object
which is the superclass of
Module
which is the superclass of
Class
so:
the "class" Class is a subclass of "class" Object
Because all of the above "Class, Module, Object, Basic Object" are instances of "class" the concept. Instance_of? Class will
return true for all them
On the other hand (Object.new).instance_of? Class will return false, because (Object.new) is an instance of "class" Object
questions:
Class.is_a? Object is true because Class is a subclass of Object but Object.is_a? Class returns true as well, is that because Class here refers to the bigger class concept? If so why? isn't that confusing? How would I know which class is which?
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
What's really going in is that Ruby is cheating. Matz wanted to copy the elegance of smalltalk when he designed Ruby, namely the rule
Everything is an object.
To put that more technically
Everything is an instance of the Object class or one of its subclasses.
However, as you've seen, that simple rule leads to some confusing situations. How does all of that craziness work? Like I said, it cheats. The Ruby interpreter is hard coded to lie about certain relationships so that the golden rule of "everything is an object" looks like it's unbroken. Here it is straight from the source:
void Init_class_hierarchy(void)
{
/* the normal hierarchy we know and love */
rb_cBasicObject = boot_defclass("BasicObject", 0);
rb_cObject = boot_defclass("Object", rb_cBasicObject);
rb_cModule = boot_defclass("Module", rb_cObject);
rb_cClass = boot_defclass("Class", rb_cModule);
/* sneaky stuff to force consistent behavior!!! */
rb_const_set(rb_cObject, rb_intern_const("BasicObject"), rb_cBasicObject);
RBASIC_SET_CLASS(rb_cClass, rb_cClass);
RBASIC_SET_CLASS(rb_cModule, rb_cClass);
RBASIC_SET_CLASS(rb_cObject, rb_cClass);
RBASIC_SET_CLASS(rb_cBasicObject, rb_cClass);
}
And there are a lot more cases in the source code where built in classes need special treatment in order to give the "least surprising" result. Basically when it comes down to abstract internal stuff like this, don't worry about it. Just assume that things will behave as expected.

What does `def self.function` name mean?

Can anyone explain to me what the meaning of adding self to the method definition is? Is it similar to the this keyword in java?
Contrary to other languages, Ruby has no class methods, but it has singleton methods attached to a particular object.
cat = String.new("cat")
def cat.speak
'miaow'
end
cat.speak #=> "miaow"
cat.singleton_methods #=> ["speak"]
def cat.speak creates a singleton method attached to the object cat.
When you write class A, it is equivalent to A = Class.new :
A = Class.new
def A.speak
"I'm class A"
end
A.speak #=> "I'm class A"
A.singleton_methods #=> ["speak"]
def A.speak creates a singleton method attached to the object A. We call it a class method of class A.
When you write
class A
def self.c_method
'in A#c_method'
end
end
you create an instance of Class(*). Inside the class definition, Ruby sets self to this new instance of Class, which has been assigned to the constant A. Thus def self.c_method is equivalent to def cat.speak, that is to say you define a singleton method attached to the object self, which is currently the class A.
Now the class A has two singleton methods, that we commonly call class methods.
A.singleton_methods
=> ["c_method", "speak"]
(*) technically, in this case where A has already been created by A = Class.new, class A reopens the existing class. That's why we have two singleton methods at the end. But in the usual case where it is the first definition of a class, it means Class.new.
In ruby self is somewhat similar to this in java, but when it comes to classes its more like the keyword static in java. A short example:
class A
# class method
def self.c_method
true
end
# instance method
def i_method
true
end
end
A.c_method #=> true
A.i_method #=> failure
A.new.i_method #=> true
A.new.c_method #=> failure
Update: Difference between static methods in java and class methods in ruby
Static methods in Java have two distinct features that makes them different from instance methods: a) they are static, b) they are not associated with an instance. (IOW: they really aren't like methods at all, they are just procedures.) In Ruby, all methods are dynamic, and all methods are associated with an instance. In fact, unlike Java where there are three different kinds of "methods" (instance methods, static methods and constructors), there is only one kind of method in Ruby: instance methods. So, no: static methods in Java are completely unlike methods in Ruby. – Jörg W Mittag 1 hour ago
When declaring a method, the self of the declaration is the declaring class/module, so effectively you are defining a class method. For the client, this works similar to a static method in java. The client would call the method on the class instead of an instance: MyClass.method
Here you can find some more details on class and instance methods.
EDIT: While the self keyword is akin to the this keyword in java, the effects of using self for class method declaration are similar to the effect of using the static keyword in java. The similarity is that static methods in java, like class methods in ruby are accessed using the class object iself instead of an instance of the class.
Please note that static does not stand for the opposite of dynamic. The choice of the name for this keyword is questionable (probably inherited from C) and rather should have been called perClass or similar to better reflect the meaning. The technical meaning is that all static members exist only once for each classloader.

Mimic another Ruby class so the object passes the === type check

I want to create an object that acts as a specific class, such as Fixnum, but isn't an instance of that class nor its subclasses.
There are various use-cases for this. In the Fixnum case, I want to define a more specific integer type that is essentially a Fixnum but implements some extra logic, too. I can't subclass Fixnum itself because immediate types such as Fixnum and Symbol can't be subclassed.
Another use-case is mocking in automated tests: sometimes you want to create an object that acts like a certain class (usually a model instance) but is for technical reasons not an instance of that exact class.
Here's how to create a specific integer type that delegates all methods to an internally stored fixnum:
require 'delegate'
require 'forwardable'
# integer representing a page number
class PageNumber < DelegateClass(Integer)
extend Forwardable
def initialize(value, name)
#name = name
super(value)
end
def inspect
"#{#name} #{to_i}"
end
alias_method :to_i, :__getobj__
def_delegators :to_i, :instance_of?, :kind_of?, :is_a?
end
This object can pass is_a? and similar checks:
page = PageNumber.new(1, "page")
page.is_a? Fixnum #=> true
But nothing I do can make it pass the Module#=== type check:
# my problem:
Fixnum === page #=> false
The fact that my object fails this check is very unfortunate, since the === method is used internally in case statements:
case page
when Fixnum
# it will never get here
when String
# ...
else
# ...
end
My question is how can I create a mock type that passes the === check without augmenting the === methods on built-in classes?
If we are speaking about the MRI1, the answer is simple: you cannot.
The Module#=== method is effectively an alias of rb_obj_is_kind_of C API method. The implementation of latter is so short that I will paste it here:
VALUE
rb_obj_is_kind_of(VALUE obj, VALUE c)
{
VALUE cl = CLASS_OF(obj);
/* Type checking of `c' omitted */
while (cl) {
if (cl == c || RCLASS_M_TBL(cl) == RCLASS_M_TBL(c))
return Qtrue;
cl = RCLASS_SUPER(cl);
}
return Qfalse;
}
As you can see, this method traverses the ancestors of the object being examined, and compares them in two ways: first, it checks if the ancestor is the same as the module which was passed, and then, it checks if they have same method table.
The latter check is required because included modules in Ruby are seemingly inserted in the inheritance chain, but as one module may be included in several other ones, it's not the real module which is inserted into the chain, but a proxy object, which has its constant and method tables pointing to the original module.
For example, let's look at Object's ancestors:
ruby-1.9.2-p136 :001 > Object.ancestors
=> [Object, Kernel, BasicObject]
ruby-1.9.2-p136 :002 > Object.ancestors.map { |mod| Object.new.is_a? mod }
=> [true, true, true]
Here, the Object and BasicObject will be successfully compared by the first check, and Kernel by the second one.
Even if you'll try to make (with a C extension) a proxy object which will try to trick the rb_obj_is_kind_of method, it will need to have the same method table as a real Fixnum, which would effectively include all Fixnum's methods.
1 I've investigated the internals for Ruby 1.9, but they behave exactly same way in 1.8.
This is a hackish solution that I warned against in my question:
Fixnum === page #=> false
Numeric.extend Module.new {
def ===(obj)
obj.instance_of?(PageNumber) or super
end
}
Fixnum === page #=> true
It solves the problem but raises a question is it safe to do? I can't think of any drawbacks of this method from the top of my mind but since we're messing with a very important method here it might not be something we'd want to do.

Ruby craziness: Class vs Object?

I just started playing with JRuby. This is my first ruby post. I had a hard time understanding classes vs objects in Ruby. It doesnt mean like what classes & objects in other Object oriented laguages. for an example
Class.is_a? Object
returns true
and
Object.is_a? Object
too.
so class & Object are both objects
here comes another one
Class.is_a? Class
returns true
and
Object.is_a? Class
too.
wait, i am not done yet
Object.instance_of? Class
Class.instance_of? Class
Both are true
Object.instance_of? Object
Class.instance_of? Object
Both are false. right, nothing can be instance of object.
And
Class.kind_of? Class
Object.kind_of? Class
both are true
Class.kind_of? Object
Object.kind_of? Object
both are true
So both are exactly same, then why do we have both these.?
After some more digging, i wrote this simple method to return method list supported by both
irb(main):054:0> def print_methods(obj)
irb(main):055:1> obj.methods.each do |mm|
irb(main):056:2* puts mm
irb(main):057:2> end
irb(main):058:1> end
Only method difference between print_methods(Object) and print_methods(Class) is
Nesting
if Nesting means inheritance, Is Object similar to the sealed class??
Can someone clarify me what is all this?
Update: To Edds comment
Interestingly i see lot of differences in the method list in
c=Class.new
print_methods(c)
&
o=Object.new
print_methods(o)
Now I understand Instance of a class is really an class instance (And this class instance is actually a Object) not an object instance. And even this instance allow me to span another instances
xx = c.new //works - c is an Object / and xx is a instance of an Object c
yy = o.new //nope - o is already a instance of an Object, so it cannot be instantiated again
So Finally, Object is really an instance of a Class. Because
xx.is_a? Class
is false, but
xx.is_a? Object
returns true
Am i right, ??
Basically the key thing to understand is that every class is an instance of the Class class and every class is a subclass of Object (in 1.8 - in 1.9 every class is a subclass of BasicObject). So every class is an object in the sense that it is an instance of a subclass of Object, i.e. Class.
Of course this means that Class is an instance of itself. If that makes your brain hurt, just don't think about it too deeply.
Object and Class are is_a? Object
x.is_a? y returns true if x.class == y or x.class < y, i.e. if x's class is y or x's class inherits from y. Since every class inherits from object x.is_a? Object returns true no matter what x is. (In 1.8 anyway, in 1.9 there's also BasicObject which is now the most basic class in the inheritance hierarchy).
They are also is_a? Class
Both Object and Class are indeed classes, so that should not be surprising.
They are also instance_of? Class, but not instance_of? Object.
Unlike is_a?, x.instance_of? y only returns true if x.class == y, not if x.class is a subclass of y. So since both x and y are instance_of? Class, they're not instance_of? Object.
right, nothing can be instance of object.
That's not true. Object.new.instance_of? Object is true.
kind_of?
kind_of? is an alias for is_a?, so see above.
So both are exactly same, then why do we have both these.?
It should be pointed out that everything up to now is true for all classes. E.g. String.is_a? Object, String.is_a? Class and String.instance_of? Class are true and String.instance_of? Object is false for the same reasons as above. (Also String.is_a? String and String.instance_of? String are both false for the same reasons - String is a class, not a string).
You can not conclude from this that all the classes are the same. They're just all instances of the same class.
Comparing methods
Since both Object and Class are classes, they both have all the instance methods defined by Class. Class additionally has the singleton method nesting. nesting tells you which module you're currently nested in, it has nothing to do with inheritance.
For any given class TheClass.methods will return the instance methods defined by Class (e.g. superclass, which returns the class which TheClass inherits from, and new which creates a new instance of TheClass) plus the singleton methods defined by that class.
Anyway methods only tells you which methods can be called directly on a given object. It does not tell you which methods can be called on an instance of a class. For that you can use instance_methods, which returns significantly different results for Object and Class.
In Ruby, everything is an Object including classes and modules. Object is the most low-level class (well, in Ruby 1.9.2 there is also BasicObject but this is an other story).
See the following output.
> Object.ancestors
# => [Object, Kernel, BasicObject]
> Class.ancestors
# => [Class, Module, Object, Kernel, BasicObject]
> Module.ancestors
# => [Module, Object, Kernel, BasicObject]
> String.ancestors
# => [String, Comparable, Object, Kernel, BasicObject]
As you can see, both Class and Module inherits from Object.
Back to your original assertions, you have to understand the difference bewteen
is_a?
kind_of'
instance_of?
They are not interchangeable. is_a? and kind_of? returns true if other is the same class or an ancestor. Conversely, instance_of? returns true only if other is the same class.
> Class.is_a? Object
# => true
> Class.kind_of? Object
# => true
> Class.instance_of? Object
# => false
One of the answers mentions this:
Basically the key thing to understand is that every class is an
instance of the Class class and every class is a subclass of Object.
So every class is an object in the sense that it is an instance of a
subclass of Object, i.e. Class.
I just want to word it differently for those who have a little brain twist. First ask yourself: What is an instance in programming? And what is a subclass in programming? An instance is just a realized variation of a blueprint (the Class). A subclass is simply a class (blueprint) that inherits from another class (blueprint). So when you create a new class:
class Apple
end
Apple is an instance of Class, that is, it is a realized variation of the blueprint. It takes the blueprint and fills in the details (methods and variables) with its own variation. Well, the blueprint inherits from another blueprint, which is Object. So every class is an instance of Class, which is a subclass of Object.
class A
end
A.superclass
=> Object
A.class
=> Class
Note Class has Module in its inheritance chain (Module included in Class as a mixin perhaps since Class's parent is Object?).
A.is_a?(Module)
=> true
Instances (A.new) of class A will have their own realized variations of A. But they are object instances. So we must distinguish class instances (e.g. class A end) and object instances ( a = A.new). Object instances have a different inheritance chain. They are a realized variation of a class instance blueprint, not a variation of class Class.
This means in their inheritance chain is not Class or Module. But rather other object instances, so if A has object instances and B has object instances and A inherits from B, when we instantiate a new object instance of A, this instance will have B instances in its inheritance chain.
They will also inherit from Object, since everything in Ruby inherits from Object.
a = A.new
=> #<A:0x007f966449b8d8>
a.is_a?(Class)
=> false
a.is_a?(Module)
=> false
a.is_a?(Object)
=> true
And this is the best way to think about it all. Do not go too deep with your thinking. Accept this as I have written it.
Ramesh, in ruby everything is an object, and a Class is no exception.
try this in irb
ruby-1.9.2-p136 :001 > o = Object.new
=> #<Object:0x000001020114b0>
ruby-1.9.2-p136 :002 > o.is_a? Class
=> false
ruby-1.9.2-p136 :003 > o.is_a? Object
=> true
in this case, I've created an instance of an Object, and checked if it's a class (false) or a Object (true).
A Class in ruby, is some kind of template object used to create instances of that class. Sorry that this is not super clear. The key concept is that ruby is a pure object oriented language, as opposed to Java.
The class/metaclass hierarchy is always a little puzzling :) Just for comparison, here's the one in Smalltalk; in Ruby, the setup is based on the same principles, except it doesn't have the Behavior and ClassDescription distinctions, and there are modules and eigenclasses to take into account.
A full explanation of the Smalltalk object model is available in Pharo by Example, as pointed by this related question.
As _why writes in this article
objects do not store methods, only classes can.
The first couple sections have some good points about classes vs objects
Think of Classes as global objects.

Extending classes and instances

This question has two parts.
In the Ruby Programming Language book, there is an example (section 8.1.1) of extending a string object and class with a module.
First question. Why is it that if you extend a class with a new method, and then create an object/instance of that class, you cannot access that method?
irb(main):001:0> module Greeter; def ciao; "Ciao!"; end; end
=> nil
irb(main):002:0> String.extend(Greeter)
=> String
irb(main):003:0> String.ciao
=> "Ciao!"
irb(main):004:0> x = "foo bar"
=> "foo bar"
irb(main):005:0> x.ciao
NoMethodError: undefined method `ciao' for "foo bar":String
from (irb):5
from :0
irb(main):006:0>
Second part, When I try to extend a Fixnum object, I get an undefined method error. Can someone explain why this works for a string but not a fixnum?
irb(main):045:0> module Greeter; def ciao; "Ciao!"; end; end
=> nil
irb(main):006:0> 3.extend(Greeter)
TypeError: can't define singleton
from (irb):6:in `extend_object'
from (irb):6:in `extend'
from (irb):6
First question. Why is it that if you
extend a class with a new method, and
then create an object/instance of that
class, you cannot access that method?
Because you extended the String class, so #ciao is a class method and not an instance method.
String.send(:include, Greeter)
x = "foo bar"
x.ciao
# => "Ciao!"
Second part, When I try to extend a
Fixnum object, I get an undefined
method error. Can someone explain why
this works for a string but not a
fixnum?
Here's the short answer.
"Fixnums, Symbols, true, nil, and
false are implemented as immediate
values. With immediate values,
variables hold the objects themselves,
rather than references to them.
Singleton methods cannot be defined
for such objects. Two Fixnums of the
same value always represent the same
object instance, so (for example)
instance variables for the Fixnum with
the value "one" are shared between all
the "ones" is the system. This makes
it impossible to define a singleton
method for just one of these."
Off course, you can include/exten the Fixnum class and every Fixnum instance will expose the methods in the Mixin.
This is exactly what Rails/ActiveSupport does in order to allow you to write
3.days.ago
1.hour.from_now
obj.extend(module) adds all the methods in module to obj. When called as String.extend(Greeter) you are adding the methods from Greeter to the instance of Class that represents String.
The easiest way to add additional instance methods to an existing class is to re-open the class. The following examples do the same thing:
class String
include Greeter
end
class String
def ciao
"Ciao!"
end
end
Fixnums (as well as Symbols, true, false and nil) are handled in a different way to normal instances. Two Fixnums with the same value will always be represented by the same object instance. As a result, Ruby doesn't allow you to extend them.
You can of course extend an instance of any other class, e.g.:
t = "Test"
t.extend(Greeter)
t.ciao
=> "Ciao!"

Resources