I know that methods in Ruby are not objects but procs and lambdas are. Is there any difference between them other than that? Because both we can pass around. What makes the proc objects different from a method?
Method:
1.8.7-p334 :017 > def a_method(a,b)
1.8.7-p334 :018?> puts "a method with args: #{a}, #{b}"
1.8.7-p334 :019?> end
1.8.7-p334 :021 > meth_ref = Object.method("a_method")
=> #<Method: Class(Object)#a_method>
1.8.7-p334 :022 > meth_ref.call(2,3)
Proc Object:
a = lambda {|a, b| puts "#{a}, #{b}"}
a.call(2,3)
In brief:
a Method object is "bound" to an object so that self points to that object when you call the method, and a Proc doesn't have that behavior; self depends on the context in which the Proc was created/called.
However:
You said in your question that "methods are not objects," but you have to be careful to distinguish between "method" and Method.
A "method" is a defined set of expressions that is given a name and put into the method table of a particular class for easy lookup and execution later:
class Foo
def my_method
return 123
end
end
Foo.new.my_method
# => 123
A Method object (or similarly an UnboundMethod object) is an actual Ruby object created by calling method / instance_method / etc. and passing the name of a "method" as the argument:
my_Foo = Foo.new
my_Method = my_Foo.method(:my_method)
# => #<Method: Foo#my_method>
my_Method.call
# => 123
my_UnboundMethod = Foo.instance_method(:my_method)
# => #<UnboundMethod: Foo#my_method>
my_UnboundMethod.bind(my_Foo).call
# => 123
A Proc object is a set of expressions that is not given a name, which you can store for later execution:
my_proc = Proc.new { 123 }
my_proc.call
# => 123
You may find it useful to read the RDoc documentation for UnboundMethod, Method, and Proc. The RDoc pages list the different instance methods available to each type.
Differences between blocks and procs
Procs are objects, blocks are not
At most one block can appear in an argument list
Differences between procs and lambdas
Lambdas check the number of arguments, while procs do not
Lambdas and procs treat the return keyword differently
It is very well explained here (I just copied that from the link below)
http://awaxman11.github.io/blog/2013/08/05/what-is-the-difference-between-a-block/
Related
irb(main):001:0> class Fixnum
irb(main):002:1> define_method(:gimme_five) do
irb(main):003:2* 5
irb(main):004:2> end
irb(main):005:1> end
=> #<Proc:0x007ff4ed01cd10#(irb):2 (lambda)>
irb(main):006:0> class String
irb(main):007:1> define_method(:scramble) do
irb(main):008:2* new_string = self.reverse()
irb(main):009:2> new_string = new_string.upcase()
irb(main):010:2> new_string
irb(main):011:2> end
irb(main):012:1> end
=> #<Proc:0x007ff4ed02d868#(irb):7 (lambda)>
irb(main):013:0>
I'm am not sure what I am doing wrong but my methods are not being defined???
In ruby, it is much more common to define methods as follows (using your output as an example:
def gimme_five
5
end
I believe that the syntax you are using to define your methods 'works', but what it is doing is creating 'lambdas' instead of regular methods. Lambdas and Procs compose Ruby's support for functional programming, and are special Ruby objects that represent blocks of code -- think of them as mini bundled up methods you can pass around to other objects.
So yeah, just define methods normally and should be fine -- the output in your irb REPL is just returning the lambda for no reason in particular -- just like how if you were to set an array in irb, you would get that array returned back:
>> a = [5]
=> [5]
I'm confused when to use each of this methods.
From respond_to? documentation:
Returns true if obj responds to the given method. Private methods
are included in the search only if the optional second parameter
evaluates to true.
If the method is not implemented, as Process.fork on Windows,
File.lchmod on GNU/Linux, etc., false is returned.
If the method is not defined, respond_to_missing? method is called and
the result is returned.
And respond_to_missing?:
Hook method to return whether the obj can respond to id method or
not.
See #respond_to?.
Both methods takes 2 arguments.
Both methods seems to the same thing(check if some object respond to given method) so why we should use(have) both?
Defining 'resond_to_missing?` gives you ability to take methods:
class A
def method_missing name, *args, &block
if name == :meth1
puts 'YES!'
else
raise NoMethodError
end
end
def respond_to_missing? name, flag = true
if name == :meth1
true
else
false
end
end
end
[65] pry(main)> A.new.method :meth1
# => #<Method: A#meth1>
Why respond_to? couldn't do this?
What I guess:
respond_to? checks if method is in:
Current object.
Parent object.
Included modules.
respond_to_missing? checks if method is:
Defined via method_missing:
Via array of possible methods:
def method_missing name, *args, &block
arr = [:a, :b, :c]
if arr.include? name
puts name
else
raise NoMethodError
end
end
Delegating it to different object:
class A
def initialize name
#str = String name
end
def method_missing name, *args, &block
#str.send name, *args, &block
end
end
2 . Other way that I'm not aware of.
Where should both be defined/used(my guessing too):
Starting from 1.9.3(as fair I remember) define only respond_to_missing? but use only respond_to?
Last questions:
Am I right? Did I missed something? Correct everything that is bad and/or answer questions asked in this question.
respond_to_missing? is supposed to be updated when you make available additional methods using the method missing technique. This will cause the Ruby interpreter to better understand the existence of the new method.
In fact, without using respond_to_missing?, you can't get the method using method.
Marc-André posted a great article about the respond_to_missing?.
In order for respond_to? to return true, one can specialize it, as follows:
class StereoPlayer
# def method_missing ...
# ...
# end
def respond_to?(method, *)
method.to_s =~ /play_(\w+)/ || super
end
end
p.respond_to? :play_some_Beethoven # => true
This is better, but it still doesn’t make play_some_Beethoven behave exactly like a method. Indeed:
p.method :play_some_Beethoven
# => NameError: undefined method `play_some_Beethoven'
# for class `StereoPlayer'
Ruby 1.9.2 introduces respond_to_missing? that provides for a clean solution to the problem. Instead of specializing respond_to? one specializes respond_to_missing?. Here’s a full example:
class StereoPlayer
# def method_missing ...
# ...
# end
def respond_to_missing?(method, *)
method =~ /play_(\w+)/ || super
end
end
p = StereoPlayer.new
p.play_some_Beethoven # => "Here's some_Beethoven"
p.respond_to? :play_some_Beethoven # => true
m = p.method(:play_some_Beethoven) # => #<Method: StereoPlayer#play_some_Beethoven>
# m acts like any other method:
m.call # => "Here's some_Beethoven"
m == p.method(:play_some_Beethoven) # => true
m.name # => :play_some_Beethoven
StereoPlayer.send :define_method, :ludwig, m
p.ludwig # => "Here's some_Beethoven"
See also Always Define respond_to_missing? When Overriding method_missing.
In python, it's fairly straightforward to reference a function:
>>> def foo():
... print "foo called"
... return 1
...
>>> x = foo
>>> foo()
foo called
1
>>> x()
foo called
1
>>> x
<function foo at 0x1004ba5f0>
>>> foo
<function foo at 0x1004ba5f0>
However, it seems to be different in Ruby since a naked foo actually calls foo:
ruby-1.9.2-p0 > def foo
ruby-1.9.2-p0 ?> print "foo called"
ruby-1.9.2-p0 ?> 1
ruby-1.9.2-p0 ?> end
=> nil
ruby-1.9.2-p0 > x = foo
foo called => 1
ruby-1.9.2-p0 > foo
foo called => 1
ruby-1.9.2-p0 > x
=> 1
How do I actually assign the function foo to x and then call it? Or is there a more idiomatic way to do this?
Ruby doesn't have functions. It only has methods (which aren't first-class) and Procs which are first-class, but are not associated with any object.
So, this is a method:
def foo(bar) puts bar end
foo('Hello')
# Hello
Oh, and, yes, this is a real method, not a top-level function or procedure or something. Methods defined at the top-level end up as private(!) instance methods in the Object class:
Object.private_instance_methods(false) # => [:foo]
This is a Proc:
foo = -> bar { puts bar }
foo.('Hello')
# Hello
Notice that Procs are called differently from methods:
foo('Hello') # method
foo.('Hello') # Proc
The foo.(bar) syntax is just syntactic sugar for foo.call(bar) (which for Procs and Methods is also aliased to foo[bar]). Implementing a call method on your object and then calling it with .() is the closest thing you will get to Python's __call__ables.
Note that an important distinction between Ruby Procs and Python lambdas is that there are no restrictions: in Python, a lambda can only contain a single statement, but Ruby doesn't have the distinction between statements and expressions (everything is an expression), and so this limitation simply doesn't exist, therefore in a lot of cases where you need to pass a named function as an argument in Python because you cannot express the logic in a single statement, you would in Ruby simply pass a Proc or a block instead, so that the problem of the ugly syntax for referencing methods doesn't even arise.
You can wrap a method in a Method object (which essentially duck-types Proc) by calling the Object#method method on an object (which will give you a Method whose self is bound to that particular object):
foo_bound = method(:foo)
foo_bound.('Hello')
# Hello
You can also use one of the methods in the Module#instance_method family to get an UnboundMethod from a module (or class, obviously, since a class is-a module), which you can then UnboundMethod#bind to a particular object and call. (I think Python has the same concepts, albeit with a different implementation: an unbound method simply takes the self argument explicitly, just like the way it is declared.)
foo_unbound = Object.instance_method(:foo) # this is an UnboundMethod
foo_unbound.('Hello')
# NoMethodError: undefined method `call' for #<UnboundMethod: Object#foo>
foo_rebound = foo_unbound.bind(self) # this is a Method
foo_rebound.('Hello')
# Hello
Note that you can only bind an UnboundMethod to an object which is an instance of the module you took the method from. You cannot use UnboundMethods to "transplant" behavior between unrelated modules:
bar = module Foo; def bar; puts 'Bye' end; self end.instance_method(:bar)
module Foo; def bar; puts 'Hello' end end
obj = Object.new
bar.bind(obj)
# TypeError: bind argument must be an instance of Foo
obj.extend(Foo)
bar.bind(obj).()
# Bye
obj.bar
# Hello
Note, however, that both the Method and the UnboundMethod are wrappers around the method, not the method itself. Methods are not objects in Ruby. (Contrary to what I have written in other answers, BTW. I really need to go back and fix those.) You can wrap them in objects, but they aren't objects, and you can see that because you essentially get all the same problems you always get with wrappers: identity and state. If you call method multiple times for the same method, you will get a different Method object every time. If you try to store some state on that Method object (such as Python-style __doc__strings, for example), that state will be private to that particular instance, and if you try to retrieve your docstring again via method, you will find that it is gone.
There is also syntactic sugar in the form of the method reference operator .::
bound_method = obj.:foo
Which is identical to
bound_method = obj.method(:foo)
You can use the method instance method inherited from Object to retrieve a Method object, which essentially is a Proc object which you can invoke call on.
In the console, you'd do this:
fooMethod = self.method(:foo) #fooMethod is a Method object
fooMethod.call #invokes fooMethod
Ruby supports proc and lambda which in other languages might be called anonymous functions or closures, depending on how they are used. They might be closer to what you are looking for.
The (main) difference between functions and methods as copied from https://stackoverflow.com/a/26620095/226255
Functions are defined outside of classes, while methods are defined
inside of and part of classes.
Ruby does not have functions and your def foo ends up being a method for the Object class.
If you insist on defining foo like you're doing above, you can extract its "functionality" by doing this:
def foo(a,b)
a+b
end
x = method(:foo).to_proc
x.call(1,2)
=> 3
Explanation:
> method(:foo) # this is Object.method(:foo), returns a Method object bound to
# object of type 'Class(Object)'
=> #<Method: Class(Object)#foo>
method(:foo).to_proc
# a Proc that can be called without the original object the method was bound to
=> #<Proc:0x007f97845f35e8 (lambda)>
Important note:
to_proc "copies" the method's object's associated instance variables if any. Consider this:
class Person
def initialize(name)
#name = name
end
def greet
puts "hello #{#name}"
end
end
greet = Person.new('Abdo').method(:greet)
# note that Person.method(:greet) returns an UnboundMethod and cannot be called
# unless you bind it to an object
> greet.call
hello Abdo
=> nil
Conceptually, if you want a "function" that would work on a certain type of objects, it should be a method and you should organize your code as such. If you only need your "function" in a certain context and wish to pass it around, use lambdas:
greet = lambda { |person| "hello #{person}" }
yell_at = lambda { |person| "HELLO #{person.upcase}" }
def do_to_person(person, m)
m.call(person)
end
do_to_person('Abdo', greet)
In a unit test I need to test whether alias methods defined by alias_method have been properly defined. I could simply use the same tests on the aliases used for their originals, but I'm wondering whether there's a more definitive or efficient solution. For instance, is there a way to 1) dereference a method alias and return its original's name, 2) get and compare some kind of underlying method identifier or address, or 3) get and compare method definitions? For example:
class MyClass
def foo
# do something
end
alias_method :bar, :foo
end
describe MyClass do
it "method bar should be an alias for method foo" do
m = MyClass.new
# ??? identity(m.bar).should == identity(m.foo) ???
end
end
Suggestions?
According to the documentation for Method,
Two method objects are equal if that
are bound to the same object and
contain the same body.
Calling Object#method and comparing the Method objects that it returns will verify that the methods are equivalent:
m.method(:bar) == m.method(:foo)
bk1e's method works most of the time, but I just happened to hit the case where it doesn't work:
class Stream
class << self
alias_method :open, :new
end
end
open = Stream.method(:open)
new = Stream.method(:new)
p open, new # => #<Method: Stream.new>, #<Method: Class#new>
p open.receiver, new.receiver # => Stream, Stream
p open == new # => false
The output is produced in Ruby 1.9, not sure if it's a bug or not since Ruby 1.8 produces true for the last line. So, if you are using 1.9, be careful if you are aliasing an inherited class method (like Class#new), These two methods are bound to the same object (the class object Stream), but they are considered not equivalent by Ruby 1.9.
My workaround is simple - alias the original method again and test the equality of the two aliases:
class << Stream; alias_method :alias_test_open, :new; end
open = Stream.method(:open)
alias_test_open = Stream.method(:alias_test_open)
p open, alias_test_open # => #<Method: Stream.new>, #<Method: Stream.new>
p open.receiver, alias_test_open.receiver # => Stream, Stream
p open == alias_test_open # => true
Hope this helps.
UPDATE:
See http://bugs.ruby-lang.org/issues/7613
So Method#== should return false in this case since a super call would invoke different methods; it is not a bug.
Calling MyClass.instance_method(:foo) will result UnboundMethod instance, which has eql? method.
So the answer is:
describe MyClass do
subject { described_class }
specify do
expect(subject.instance_method(:foo)).to be_eql(subject.instance_method(:bar))
end
end
Is it possible to convert a proc-flavored Proc into a lambda-flavored Proc?
Bit surprised that this doesn't work, at least in 1.9.2:
my_proc = proc {|x| x}
my_lambda = lambda &p
my_lambda.lambda? # => false!
This one was a bit tricky to track down. Looking at the docs for Proc#lambda? for 1.9, there's a fairly lengthy discussion about the difference between procs and lamdbas.
What it comes down to is that a lambda enforces the correct number of arguments, and a proc doesn't. And from that documentation, about the only way to convert a proc into a lambda is shown in this example:
define_method always defines a method without the tricks, even if a non-lambda Proc object is given. This is the only exception which the tricks are not preserved.
class C
define_method(:e, &proc {})
end
C.new.e(1,2) => ArgumentError
C.new.method(:e).to_proc.lambda? => true
If you want to avoid polluting any class, you can just define a singleton method on an anonymous object in order to coerce a proc to a lambda:
def convert_to_lambda &block
obj = Object.new
obj.define_singleton_method(:_, &block)
return obj.method(:_).to_proc
end
p = Proc.new {}
puts p.lambda? # false
puts(convert_to_lambda(&p).lambda?) # true
puts(convert_to_lambda(&(lambda {})).lambda?) # true
It is not possible to convert a proc to a lambda without trouble. The answer by Mark Rushakoff doesn't preserve the value of self in the block, because self becomes Object.new. The answer by Pawel Tomulik can't work with Ruby 2.1, because define_singleton_method now returns a Symbol, so to_lambda2 returns :_.to_proc.
My answer is also wrong:
def convert_to_lambda &block
obj = block.binding.eval('self')
Module.new.module_exec do
define_method(:_, &block)
instance_method(:_).bind(obj).to_proc
end
end
It preserves the value of self in the block:
p = 42.instance_exec { proc { self }}
puts p.lambda? # false
puts p.call # 42
q = convert_to_lambda &p
puts q.lambda? # true
puts q.call # 42
But it fails with instance_exec:
puts 66.instance_exec &p # 66
puts 66.instance_exec &q # 42, should be 66
I must use block.binding.eval('self') to find the correct object. I put my method in an anonymous module, so it never pollutes any class. Then I bind my method to the correct object. This works though the object never included the module! The bound method makes a lambda.
66.instance_exec &q fails because q is secretly a method bound to 42, and instance_exec can't rebind the method. One might fix this by extending q to expose the unbound method, and redefining instance_exec to bind the unbound method to a different object. Even so, module_exec and class_exec would still fail.
class Array
$p = proc { def greet; puts "Hi!"; end }
end
$q = convert_to_lambda &$p
Hash.class_exec &$q
{}.greet # undefined method `greet' for {}:Hash (NoMethodError)
The problem is that Hash.class_exec &$q defines Array#greet and not Hash#greet. (Though $q is secretly a method of an anonymous module, it still defines methods in Array, not in the anonymous module.) With the original proc, Hash.class_exec &$p would define Hash#greet. I conclude that convert_to_lambda is wrong because it doesn't work with class_exec.
Here is possible solution:
class Proc
def to_lambda
return self if lambda?
# Save local reference to self so we can use it in module_exec/lambda scopes
source_proc = self
# Convert proc to unbound method
unbound_method = Module.new.module_exec do
instance_method( define_method( :_proc_call, &source_proc ))
end
# Return lambda which binds our unbound method to correct receiver and calls it with given args/block
lambda do |*args, &block|
# If binding doesn't changed (eg. lambda_obj.call) then bind method to original proc binding,
# otherwise bind to current binding (eg. instance_exec(&lambda_obj)).
unbound_method.bind( self == source_proc ? source_proc.receiver : self ).call( *args, &block )
end
end
def receiver
binding.eval( "self" )
end
end
p1 = Proc.new { puts "self = #{self.inspect}" }
l1 = p1.to_lambda
p1.call #=> self = main
l1.call #=> self = main
p1.call( 42 ) #=> self = main
l1.call( 42 ) #=> ArgumentError: wrong number of arguments (1 for 0)
42.instance_exec( &p1 ) #=> self = 42
42.instance_exec( &l1 ) #=> self = 42
p2 = Proc.new { return "foo" }
l2 = p2.to_lambda
p2.call #=> LocalJumpError: unexpected return
l2.call #=> "foo"
Should work on Ruby 2.1+
Cross ruby compatiable library for converting procs to lambdas:
https://github.com/schneems/proc_to_lambda
The Gem:
http://rubygems.org/gems/proc_to_lambda
The above code doesn't play nicely with instance_exec but I think there is simple fix for that. Here I have an example which illustrates the issue and solution:
# /tmp/test.rb
def to_lambda1(&block)
obj = Object.new
obj.define_singleton_method(:_,&block)
obj.method(:_).to_proc
end
def to_lambda2(&block)
Object.new.define_singleton_method(:_,&block).to_proc
end
l1 = to_lambda1 do
print "to_lambda1: #{self.class.name}\n"
end
print "l1.lambda?: #{l1.lambda?}\n"
l2 = to_lambda2 do
print "to_lambda2: #{self.class.name}\n"
end
print "l2.lambda?: #{l2.lambda?}\n"
class A; end
A.new.instance_exec &l1
A.new.instance_exec &l2
to_lambda1 is basically the implementation proposed by Mark, to_lambda2 is a "fixed" code.
The output from above script is:
l1.lambda?: true
l2.lambda?: true
to_lambda1: Object
to_lambda2: A
In fact I'd expect instance_exec to output A, not Object (instance_exec should change binding). I don't know why this work differently, but I suppose that define_singleton_method returns a method that is not yet bound to Object and Object#method returns an already bound method.