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/.
Related
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.
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
In the Ruby Programming Language, Chapter 6 (second paragraph) they state:
Many languages distinguish between
functions, which have no associated
object, and methods, which are invoked
on a receiver object. Because Ruby is
a purely object oriented language, all
methods are true methods and are
associated with at least one object.
And then in the middle of the 6th paragraph:
Both procs and lambdas are functions
rather than methods invoked on an
object.
I am a bit confused about these statements. Is Ruby truly pure OO, and therefore doesn't have functions that aren't associated with objects (if that is a valid definition of pure OO), or are procs/lambdas associated with the Proc object? What is the difference between functions and methods in Ruby?
Any help in parsing and understanding this would be appreciated.
lambdas in Ruby are objects of class Proc. Proc objects don't belong to any object. They are called without binding them to an object.
Methods are objects of either class Method or UnboundMethod, depending on whether they're bound or unbound. See the explanation here. Unbound methods can't be called until they're bound to an object.
lambda{|x| x}.class # => Proc
lambda{|x| x}.call(123) # => 123
class Foo
def bar(baz)
baz
end
end
puts Foo.new.method(:bar).class # => Method
puts Foo.new.method(:bar).call(123) # => 123
puts Foo.instance_method(:bar).class # => UnboundMethod
puts Foo.instance_method(:bar).call(123) # => throws an exception
You can bind an UnboundMethod to an object and then call it. But you can't bind a Proc to an object at all. Proc objects can however capture local variables in the surrounding scope, becoming closures.
Procs and lambdas are both objects unto themselves, with a call method that actually invokes the block associated with the proc (or lambda). However, Ruby provides some syntactic sugar to invoke them without the explicit call to call.
I think the distinction is between methods and first order function ie. functions that can be passed around as values.
we can call the Array method in the top level like this
Array(something)
that makes sense to me, it's a method call without explicit receiver, and self, which is main in this case, is inserted at the front of the method call. But isn't it that this is equivalent to :
Kernel.Array(something)
this doesn't make sense to me. Since in the first case, the object main is of class Object, which got Kernel module mixed in, thus have the Array method. But in the second case, we are calling the Array method on the Kernel module object itself, rather than main object, didn't they are NOT the same thing?
sorry for my bad english.
Kernel.Array is what is known as a module function. Other examples of module functions include Math.sin, and Math.hypot and so on.
A module function is a method that is both a class method on the module and also a private instance method. When you invoke Array() at the top-level you are invoking it as a private instance method of the main object. When you invoke it through Kernel.Array() you are invoking it as a class method on Kernel. They are the same method.
To learn more, read up on the module_function method in rubydocs: http://www.ruby-doc.org/core/classes/Module.html#M001642
class Object mixed-in module Kernel, but Kernel is an instance of Object. So Kernel "module" methods - is it's instance methods.
What's confusing you is the difference between class and instance methods.
Class methods don't have an explicit receiver, and thus no self to access other fields with. They just... are.
Generally instance methods are used to query or manipulate the attributes of a given object, whereas the class methods are "helper" or "factory" methods that provide some functionality associated with or especially useful for a certain kind of class, but not dependent on actual live instances (objects) of that class.
Not sure about Ruby, but Java has (for example) a whole class, Math that contains nothing but instance methods like sin(), max(), exp() and so forth: There is no "Math" object, these are just methods that embody mathematical algorithms. Not the best example, because in Ruby those methods are probably embedded right into the numeric classes as instance methods.
The case you mention is a bit confusing because Array's () method and Kernel's Array() method are in fact different methods that do similar things. Both are class methods.
Array() takes a list of arguments and makes and returns an array containing them.
Kernel.Array() takes a single argument of an "array-able" type, such as a sequence, and takes the values returned by this argument and builds an array from those.
UPDATE
The downvote was perhaps justified; I apologize for taking on a subject outside my area of expertise. I think I'll be deleting this answer soon.
# Chuck: I would sincerely hope that a language/library's official documentation would offer some meaningful clues as to how it works. This is what I consulted in answering this question.
The rdoc for Kernel.Array():
Returns arg as an Array. First tries to call arg.to_ary, then arg.to_a. If both fail, creates a single element array containing arg (unless arg is nil).
for Array.():
Returns a new array populated with the given objects.
I don't know about you, but I think if the docs vary that much then either they're talking about separate methods or the documentation is a train wreck.
# freeknight:
But everything in ruby is an object of some kind, even classes and modules. And Kernel.Array is actually a method call on an specific object - the Kernel object.
Yeah, under the covers it's similar in Java too. But the Array() method isn't doing anything with Kernel, any more than Array() is doing anything with the Array class object, so this is really only a semantic quibble. It's an instance method because you could hang it off class IPSocket if you were crazy enough, and it would still work the same way.
They are the same thing:
a = Kernel.Array('aa')
=> ["aa"]
a.class
=> Array
a = Array('aaa')
=> ["aaa"]
a.class
=> Array
Maybe there is an alias?
method_missing
*obj.method_missing( symbol h , args i ) → other_obj
Invoked by Ruby when obj is sent a
message it cannot handle. symbol is
the symbol for the method called, and
args are any arguments that were
passed to it. The example below
creates a class Roman, which responds
to methods with names consisting of
roman numerals, returning the
corresponding integer values. A more
typical use of method_missing is to
implement proxies, delegators, and
forwarders.
class Roman
def roman_to_int(str)
# ...
end
def method_missing(method_id)
str = method_id.id2name
roman_to_int(str)
end
end
r = Roman.new
r.iv ! 4
r.xxiii ! 23
r.mm ! 2000
I just heard about method-missing and went to find out more in Programming Ruby but the above explanation quoted from the book is over my head. Does anyone have an easier explanation? More specifically, is method-missing only used by the interpreter or is there ever a need to call it directly in a program (assuming I'm just writing web apps, as opposed to writing code for NASA)?
It's probably best to not think of ruby as having methods. When you call a ruby "method" you are actually sending a message to that instance (or class) and if you have defined a handler for the message, it is used to process and return a value.
So method_missing is a special definition that gets called whenever ruby cannot find an apropriate handler. You could also think of it like a * method.
Ruby doesn't have any type enforcement, and likewise doesn't do any checking as to what methods an object has when the script is first parsed, because this can be dynamically changed as the application runs.
What method_missing does, is let you intercept and handle calls to methods that don't exist for a given object. This provides the under-the-hood power behind pretty much every DSL (domain-specific language) written in Ruby.
In the case of the example, every one of 'r.iv', 'r.mm', and so on is actually a method call to the Roman object. Of course, it doesn't have an 'iv' or an 'mm' method, so instead control is passed to method_missing, which gets the name of the method that was called, as well as whatever arguments were passed.
method_missing then converts the method name from a symbol to a string, and parses it as a Roman number, returning the output as an integer.
It's basically a catch-all for messages that don't match up to any methods. It's used extensively in active record for dynamic finders. It's what lets you write something like this:
SomeModel.find_by_name_and_number(a_name, a_number)
The Model doesn't contain code for that find_by, so method_missing is called which looks at is says - I recognize that format, and carries it out. If it doesn't, then you get a method not found error.
In the Roman example you provide it illustrates how you can extend the functionality of a class without explicitly defining methods.
r.iv is not a method so method_missing catches it and calls roman_to_int on the method id "iv"
It's also useful when you want to handle unrecognized methods elsewhere, like proxies, delegators, and forwarders, as the documentation states.
You do not call "method_missing" (the interpreter calls it). Rather, you define it (override it) for a class which you want to make to be more flexible. As mentioned in other comments, the interpreter will call your version of method_missing when the class (or instance) does not ("explicitly"?) define the requested method. This gives you a chance to make something up, based on the ersatz method/message name.
Have you ever done any "reflection" programming in Java? Using this method would be as if the class to be accessed via reflection could look at the string (excuse me, "symbol") of the method name if a no-such-method exception was thrown, and then make something up as that method's implementation on the fly.
Dynamic programming is kind of a "one-up" on reflection.
Since you mention web apps I'll guess that you are familiar with Ruby on Rails. A good example of how method_missing can be used is the different find_by_<whatever> methods that's available. None of those methods actually exist! They are synthesized during run time. All of this magic happens because of how ruby intercepts invocations of non-existing methods.
You can read more about that and other uses of method_missing here.
ActiveRecord uses method_missing to define find_by methods. But since, method_missing is basically a last resort method, this can be a serious performance bottleneck. What I discovered is that ActiveRecord does some further awesome metaprogramming by defining the new finder method as a class method !! Thus, any further calls to the same finder method would not hit the method_missing because it is now a class method. For details about the actual code snippet from base.rb, click here.