What is the difference in calling a method explicitely and implicitely? - ruby

As per my understanding, in ruby we cannot call private method on self (calling private methods on self explicitly is not possible). If you call a method without any receiver, then it gets called on self, Then why cant we call a private method with self itself?
Sorry but I didn't really get what exactly is the difference in calling explicitly and implicitly(with self and without self).
I know that I may get down votes but still want to know. Can anyone tell me please.

At least in MRI, these concepts are identical. An explicit call is a public call, an implicit call is a private call.
The parser recognizes three kinds of method calls:
methods with an explicit receiver e.g. obj.foo(1)
methods with an implicit receiver e.g. foo(1)
methods with an implicit receiver and no arguments e.g. foo
The evaluator recognizes each of these as a different "call type". These types are (respectively):
CALL_PUBLIC
CALL_FCALL
CALL_VCALL
This call type is checked before making the call:
if (((noex & NOEX_MASK) & NOEX_PRIVATE) && scope == CALL_PUBLIC) {
return NOEX_PRIVATE;
}
I.e. if the method is private and the call type is public, don't call the method (protected calls work the same way but also check the receiver's class).
So whenever there is an explicit receiver (even if it's self inside an instance method definition), that call is a "public call".

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).

Ruby Kernel#autoload and Module#autoload difference

What is the difference between Kernel#autoload and Module#autoload? What is the context in which each is used?
As it might be seen in source code of these methods in standard documentation, Kernel#autoload calls Module#autoload after casting the receiver to it’s class.
When one uses the most common approach and calls autoload on the class level:
class C
autoload(:M, 'm')
end
the Module#autoload is called because Class < Module. Since the receiver is in this case already a Class’ instance, there is no necessity in explicit cast.
On the other hand, one might need to call autoload within a method body:
class C
def c
autoload(:M, 'm')
end
end
In the latter case the receiver is an instance, and unless it’s a Module descendant, Kernel#autoload is called, which, in turn, retrieves the class of this instance and passes the call to it’s Module#autoload.

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.

True proc from a method

Is there a way to get a true proc from a method in Ruby?
An UnboundMethod obtained via instance_method does not fit the bill because I can only bind it to an object of the class that declared the method. I can't reinterpret self inside the method body the way I could in a proc (using instance_exec).
Similarly, a Method obtained via method is not okay, because self is bound to the receiver of method and I cannot change it.
Edit (Clarification):
What I'm trying to do is to take a method defined in one class and transfer it to another class. This means I need to be able to reinterpret the meaning of self within the method. For procs, this is possible via instance_exec and instance_eval, but not for methods.
Why I am trying to move methods from one class to another? Long story short, to implement a form of namespacing, as I am most displeased with the visibility control provided by Ruby (there is no way to hide a module member to an including class). This is however far beyond the scope of this question.
Maybe to_proc from Method can help you:
class A
def test
puts 'this is a test'
end
end
m = A.new.method(:test)
m.to_proc.call #=> this is a test
UPDATE: Just an idea
By using sourcify gem convert proc from first object to source, and then evaulate it in the context of second object

Do ruby Proc/lambda have a 'this' function like javascript closure ?

In javascript closure, 'this' reference to the object which actually make the function call.
Do ruby Proc/lambda have 'this' function too?
If not, what should I do to if I want 'this' in ruby? except passing the current object to Proc/lambda by parameters.
this is not part of the concept of a function or closure in general. A function is simply a thing you can call with arguments; what does "current object" has to do with it? this existing in all functions in JavaScript comes from the peculiar way that methods work in that language.
In JavaScript, all functions have a concept of this because in JavaScript, there is no separation between methods and functions. Any function could potentially be used as a method; you can add a method to an object simply by assigning a function as an attribute of the object. Furthermore, in JavaScript, a function does not have an explicit parameter for the current object (unlike e.g. Python); so how does a method have access to its object? When you run a method call expression, it will pass the object that you called it on as an implicit this parameter to the function. However, if you get the function out using the attribute and call it manually just like any other function, this will be the global object (or in strict mode, undefined).
In other words, in JavaScript when you get a method out of an object by attribute, it is an "unbound method" -- it does not know the object it came from; and conversely when you put a function into an object as a method by attribute, that function did not need to know the object to start with -- the object will be passed to it magically by the method call syntax at the time it is called. You can also artificially supply the this argument to a function by using the .call() or .apply() methods on the function (obj.foo(x) is equivalent to obj.foo.call(obj, x)).
In Ruby, there is complete separation between methods and anonymous functions. Anonymous functions, created using lambda, proc, or Proc.new, etc. are data, and can be stored in variables. They are called with different syntax (call or []) than methods. Methods are defined using def, and you can't get it as data by simply writing its name (that will call it). It is possible to get a method out of an object using the method method on an object, giving the method name, and it returns a Method object. You can use a Method object like a Proc object, e.g. you can call call on it; you can even convert it to a Proc with to_proc. Unlike JavaScript, there is a distinction between bound methods (class Method) an unbound methods (class UnboundMethod). When you get a method out of an object, it is bound -- it knows its object; you can unbind it and bind it to another object if you want.
Also, in Ruby, you can't just take a Proc and just attach it to an object and make it a method, because methods have syntax (e.g. #some_var) that are not valid in Proc. To add a method to an object, you would use instance_exec and put the method definition (def) in the block.
So in short, the concept of this in closures deals with a unique situation in JavaScript not found in most languages. And in particular, the issue does not come up in Ruby because Ruby's objects' methods are bound methods, and also one cannot arbitrarily insert closures as methods.
P.S. others have commented on capturing the self from where a closure is defined into the closure. However, that's not what this in JavaScript is about at all.
You can use self if you initialize the lambda or proc within a Ruby object. For example:
class Example
def name
"Example"
end
def test
lambda{ puts self.name}.call
end
end
example = Example.new
example.test # "Example"
For a more detailed explanation of Ruby's self see: http://sidtalk.wordpress.com/2008/10/06/what-exactly-is-ruby-self/.

Resources