What is the difference between Super thing = new Sub() and Sub thing = new Sub()? - subclass

Super thing = new Sub();
Sub thing = new Sub();
What is the difference in terms of accessing thing and what I can do with it etc?

The difference is that the variabele Super thing can be reassigned to any other subclass that implements Super, whereas Sub thing of course can only be assigned to another Sub class.
That said, assigning new Sub() to Super thing uses polymorphism and overriding, of which you can find a good tutorial here and here. You can only call the methods defined in the class Super. If these methods are overridden (read: redefined) in one of the subclasses, polymorphism will make sure the overridden method is called, instead of the method in the class Super.

Related

Why do we have implicit receiver in Ruby?

I have two questions regarding Ruby core OOP concepts.
I understand the differences between explicit call (i.e. with self) and implicit call (i.e. without initialized class object or self in an instance method) of a method. When we have explicit receivers that do very neat and clear job of receiving a method with self (since it refers to the current object) rather than implicit ones (which I believe is very uncertain in situations like when to use method or variable of same name initialized), then why do we still have to call methods implicitly? Is it just a preference or is it necessary because of proper usage of private and public methods?.
In general, OOP private methods are bound within the class itself and cannot be accessed in subclasses or outside. However, those methods that need to be private but also need to be accessed in subclasses then protected methods are used over there. But in Ruby, both private and
protected methods are accessed in inherited classes, and the only difference is that private methods can only be called implicitly and protected methods can either be called implicitly or explicitly. I don't understand the philosophy over here that only because of implicit calling functionality in ruby, general definitions of private methods differ?
I think you have a slight misunderstanding of the purpose of protected methods. Protected methods can be called from methods of another instance of the same class.
class Person
def initialize(name, age)
#name = name
#age = age
end
def older_than?(other_person)
age > other_person.age
end
protected
def age
#age
end
end
mother = Person.new('Carole', 34)
father = Person.new('George', 37)
If you try...
mother.age
=>NoMethodError: protected method `age' called for #<Person:0x0000000327daa0 #name="Carole", #age=34>
So you cannot, externally, call the #age method.
But you can do...
father.older_than?(mother)
=> true
So the father object was able to call the mother object #age method, because he is an object of the same class Person.
In the discussion below, recall that the only way to call an instance method with an implicit receiver (self) is to do so from within an instance method of the same class.
The question is why Ruby was designed to permit most1 instance methods to be called with an implicit receiver.
One would probably have to ask Matz to get an authoritative answer, but my guess is that it traces back to the way private instance methods were implemented. Requiring that they be called with an implicit receiver was seen (I'm guessing) as a simple way to prevent them from being called from anywhere other than from within an instance method of the same class.
But if private methods must be called with an implicit receiver, in the interest of consistency wouldn't it have made sense to permit (nearly all) public and protected instance methods to be called with an implicit receiver?
Some Rubiests see the use of the explicit receiver self as redundant, and therefore use an implicit receiver (except where self. is required). Others see the use of implicit receivers as a potential source of confusion, so use self., knowing (or possibly not knowing), that is optional. So far as I know, all core Ruby methods implemented in Ruby use implicit receivers. Those in the first camp might argue that using self. redundantly is akin to saying "Meet me at the blue wall that is colored blue".
1 There are a handful of cases where the explicit receiver self is required to avoid ambiguity. The two most common are when invoking the method class (considering class is also a keyword) and invoking a setter, which Ruby might otherwise confuse with the assignment of a value to a newly-created local variable. Another example is that we cannot write Array methods def a; [1]; end nor def a; [](1); end. Again, an explicit receiver is needed: self[1] or self.[](1).

If "puts" method is a private instance method, why can we call it from anywhere?

I have read that "puts" is a private instance method of the module Kernel (and therefore of Object, since Object mixes in Kernel).
That's why when we call puts, we don't specify a explicit receiver. My question is, if it's a private instance method, how is it possible that we can call it from any other scope? So, we can do:
class Test
puts "hello" # self is Test. So, we are calling self.puts "hello" -
end
What am I missing here? How is it possible that this works? We are calling a private instance method?
EDIT:
Same question arises if I do this:
class Object
private
def talk
puts "hi there"
end
end
class Test
talk # outputs 'hi there'
end
Why is it possible that from class Test we can call a private method from the class Object?
Please have a look at the doc for the Kernel module - http://www.ruby-doc.org/core-2.0.0/Kernel.html.
Unlike Java, Ruby is not limited to Classes as containers of implementations. Modules act as wonderful containers which can be mixed into other classes. When a module is mixed into another class, all its instance methods become instance methods of those class. Since the Kernel module is mixed into the Object class, its methods are therefore available in all Ruby classes.
Please read the following:
Ruby access control
Common misunderstanding and clarification about access controls in Ruby
With the risk of duplication, I have to say this: private in Ruby is not the same as in C++ or Java. Subclasses of a class can call private methods declared in their superclass. In fact, you can call private method of any class using :send. The only difference between private and protected methods is that private methods can't be called with explicit receivers.
Even the last rule has an exception. If your private method is something like age=, it can (and has to be) called with self. Funny, isn't it? :)
UPDATE: (to explain the gist):
The talk method which you wrote in your code above is being called on the main object which is the context for all Ruby programs. It's not being called on the Test class which is why it's not working for your second gist.
In the gist that I have provided, talk is a private class method which is why it gets executed at the time of class definition. In the same gist, the talk2 method is an instance method and can only be called from within instance methods. Your example gist didn't work because you were trying to invoke an instance method at the time of defining the class.
I don't understand why such long answer as in the other answer is required, or is upvoted. The answer to your question is simple.
It is because almost all classes (i.e., anything other than BasicObject) includes Kernel. Therefore, in the scope of a usual object, Kernel class is inherited, and hence its methods are accessible. That is all.

Is there any reason to use Classname.new keyword in ruby other than when creating an instance of an object in a main

This class takes in a hash, and depending on the input, it converts temperatures.
class Temp
def initialize(opt={})
if opt.include?(:cold)
#colddegree=opt[:cold]
end
end
def self.from_cold(cel)
Temp.new(:cold => cel) <= instance of class created in class method
end
end
An instance of a class is created inside a class method. Why is it necessary to do so, and what it does it do, what is the reasoning behind it?
Why would we need to create an instance of a class inside the class instead of the main?
Why would it be used inside a class method? Can there be a time when it would be required inside a regular object methods?
What is it calling and what is happening when it is creating an instance inside a class method? what difference does it make?
Rubyists don't always use the word, but self.from_cold is a factory. This allows you to expose a Temp.from_cold(-40) method signature that programmers consuming your API can understand readily without having to concern themselves with the boilerplate of, say, learning that you have an implicitly required parameter named :cold.
It becomes extra useful when you have a work-performing object that needs to be initialized and then invoked, such as TempConverter.new(cel: -40).to_fahrenheit. Sometimes it's cleaner to expose a TempConverter.cel_to_fahr(-40) option to be consumed by other libraries. It's mostly just a way of hiding complexity inside of this class so that other classes with temp conversion needs don't have to violate the Law of Demeter.
An important thing to understand is that unlike C#, JavaScript, or C++, new is not a keyword in Ruby. It's just a message which objects of class Class understand. The default behaviour is to allocate and initialize a new object of that class, but there's nothing stopping you overriding it, for example:
class Foo
def self.new
puts "OMG i'm initializing an object"
super
end
end
So to answer your last question, it makes no difference where Temp.new is called. In all cases, it sends the message new to the object Temp (which is also a class, but remember that almost everything in Ruby is an object, including classes), which creates and returns a new instance.
I'm not going to attempt to answer your other two questions, because the other answer already does.

Does ruby call initialize method automatically?

Do I need to explicitly initialize an object if an initialize method is included in class definition?
No, Ruby does not call initialize automatically.
The default implementation of Class#new looks a bit like this:
class Class
def new(*args, &block)
obj = allocate
obj.initialize(*args, &block)
obj
end
end
[Actually, initialize is private by default so you need to use obj.send(:initialize, *args, &block).]
So, the default implementation of Class#new does call initialize, but it would be perfectly possible (albeit extremely stupid) to override or overwrite it with an implementation that does not.
So, it's not Ruby that calls initialize, it's Class#new. You may think that's splitting hairs, because Class#new is an integral part of Ruby, but the important thing here is: it's not some kind of language magic. It's a method like any other, and like any other method it can be overridden or overwritten to do something completely different.
And, of course, if you don't use new to create an object but instead do it manually with allocate, then initialize wouldn't be called either.
There are some cases where objects are created without calling initialize. E.g. when duping or cloneing, initialize_dup and initialize_clone are called instead of initialize (both of which, in turn, call initialize_copy). And when deserializing an object via, say, Marshal, its internal state is reconstructed directly (i.e. the instance variables are set reflectively) instead of through initialize.
Yes, it's called from new method, which you use to create objects.
It depends on your definition of "explicit". Usually you need to, even if there are no arguments:
object = MyClass.new(...)
In some cases there are factory methods that produce instances you can use, creating a form of implicit initialization:
object = MyClass.factory_method(...)
This would have the effect of calling MyObject.new internally.
There are some libraries which have rather unusual method signatures, like:
object = MyClass(...)
object = MyClass[...]
The effect is the same, as these might look odd but are just method calls.

Static block in Ruby

I have been a Java programmer for a while and I am trying to switch to ruby for a while. I was just trying to develop a small test program in ruby and my intention is something like following.
I want to create a simple linked list type of an object in ruby; where an instance variable in class points to another instance of same type.
I want to populate and link all nodes; before the constructor is called and only once. Something that we'd usually do in Java Static block.
Initialize method is a constructor signature in ruby. Are there any rules around them? Like in Java you cannot call another constructor from a constructor if its not the first line (or after calling the class code?)
Thanks for the help.
-Priyank
I want to create a simple linked list type of an object in ruby; where an instance variable in class points to another instance of same type.
Just a quick note: the word type is a very dangerous word in Ruby, especially if you come from Java. Due to an historic accident, the word is used both in dynamic typing and in static typing to mean two only superficially related, but very different things.
In dynamic typing, a type is a label that gets attached to a value (not a reference).
Also, in Ruby the concept of type is much broader than in Java. In Java programmer's minds, "type" means the same thing as "class" (although that's not true, since Interfaces and primitives are also types). In Ruby, "type" means "what can I do with it".
Example: in Java, when I say something is of type String, I mean it is a direct instance of the String class. In Ruby, when I say something is of type String, I mean it is either
a direct instance of the String class or
an instance of a subclass of the String class or
an object which responds to the #to_str method or
an object which behaves indistinguishably from a String.
I want to populate and link all nodes; before the constructor is called and only once. Something that we'd usually do in Java Static block.
In Ruby, everything is executable. In particular, there is no such thing as a "class declaration": a class body is just exectuable code, just like any other. If you have a list of method definitions in your class body, those are not declarations that are read by the compiler and then turned into a class object. Those are expressions that get executed by the evaluator one by one.
So, you can put any code you like into a class body, and that code will be evaluated when the class is created. Within the context of a class body, self is bound to the class (remember, classes are just objects like any other).
Initialize method is a constructor signature in ruby. Are there any rules around them? Like in Java you cannot call another constructor from a constructor if its not the first line (or after calling the class code?)
Ruby doesn't have constructors. Constructors are just factory methods (with stupid restrictions); there is no reason to have them in a well-designed language, if you can just use a (more powerful) factory method instead.
Object construction in Ruby works like this: object construction is split into two phases, allocation and initialization. Allocation is done by a public class method called allocate, which is defined as an instance method of class Class and is generally never overriden. It just allocates the memory space for the object and sets up a few pointers, however, the object is not really usable at this point.
That's where the initializer comes in: it is an instance method called initialize, which sets up the object's internal state and brings it into a consistent, fully defined state which can be used by other objects.
So, in order to fully create a new object, what you need to do is this:
x = X.allocate
x.initialize
[Note: Objective-C programmers may recognize this.]
However, because it is too easy to forget to call initialize and as a general rule an object should be fully valid after construction, there is a convenience factory method called Class#new, which does all that work for you and looks something like this:
class Class
def new(*args, &block)
obj = alloc
obj.initialize(*args, &block)
return obj
end
end
[Note: actually, initialize is private, so reflection has to be used to circumvent the access restrictions like this: obj.send(:initialize, *args, &block)]
That, by the way, is the reason why to construct an object you call a public class method Foo.new but you implement a private instance method Foo#initialize, which seems to trip up a lot of newcomers.
To answer your question: since an initializer method is just a method like any other, there are absolutely no restrictions as to what you can do whithin an initializer, in particular you can call super whenever, wherever, however and how often you want.
BTW: since initialize and new are just normal methods, there is no reason why they need to be called initialize and new. That's only a convention, although a pretty strong one, since it is embodied in the core library. In your case, you want to write a collection class, and it is quite customary for a collection class to offer an alternative factory method called [], so that I can call List[1, 2, 3] instead of List.new(1, 2, 3).
Just as a side note: one obvious advantage of using normal methods for object construction is that you can construct instances of anonymous classes. This is not possible in Java, for absolutely no sensible reason whatsoever. The only reason why it doesn't work is that the constructor has the same name as the class, and anonymous classes don't have a name, ergo there cannot be a constructor.
Although I am not quite sure why you would need to run anything before object creation. Unless I am missing something, shouldn't a list basically be
class List
def initialize(head=nil, *tail)
#head = head
#tail = List.new(*tail) unless tail.empty?
end
end
for a Lisp-style cons-list or
class List
def initialize(*elems)
elems.map! {|el| Element.new(el)}
elems.zip(elems.drop(1)) {|prv, nxt| prv.instance_variable_set(:#next, nxt)}
#head = elems.first
end
class Element
def initialize(this)
#this = this
end
end
end
for a simple linked list?
You can simply initialize your class variables in the class body, outside of any method declaration. It will behave like a static initializer in Java:
class Klass
##foo = "bar"
def sayFoo
puts ##foo
end
def self.sayFoo
puts ##foo
end
end
The class field ##foo is here initialized to "bar".
In ruby object creation works like this
class Class
def new(*args)
obj= self.allocate # get some memory
obj.send(:initialize) # call the private method initialize
end
end
Object#initialize is just an ordinary private method.
If you wan't something to happen before Object#initialize you have to write your own Class#new. But I see no reason why you would want to do that.
This is basically the same answer paradigmatic gave back in '09.
Here I want to illustrate that the "static initializer" can call other code. I'm simulating a scenario of loading a special user once, upon class initialization.
class Foo
def user
"Thomas"
end
end
class Bar
##my_user = Foo.new.user
def my_statically_defined_user
##my_user
end
end
b = Bar.new
puts b.my_statically_defined_user # ==> Thomas

Resources