In Ruby everything are Objects except Functions / Methods?

Hiii,

i am new to this ruby-talk list, so i hope my question is not annoying
(especially for my not so goood english).

My question is simple. Is there a way to store a method in a variable? I
know that every method can be called with the keyword and send, but is
there a way to make it direct callable?

As example:

def addition(a, b)
a + b
end

x = addition
x(2, 3) # => 5

Is there a method like partial or anything like this in ruby?

best wishes,

Adrian


@addisaden

On Mon, Jun 30, 2014 at 5:58 PM, Addis A. [email protected]
wrote:

def addition(a, b)
a + b
end

x = addition
x(2, 3) # => 5

Is there a method like partial or anything like this in ruby?

2.0.0p195 :001 > def addition(a, b)
2.0.0p195 :002?> a + b
2.0.0p195 :003?> end
2.0.0p195 :006 > x = method(:addition)
=> #<Method: Object#addition>
2.0.0p195 :010 > x.call 2, 3
=> 5

The standalone method is still bound to the object:

2.0.0p195 :011 > class A
2.0.0p195 :012?> def initialize a
2.0.0p195 :013?> @a = a
2.0.0p195 :014?> end
2.0.0p195 :015?> def addition y
2.0.0p195 :016?> @a + y
2.0.0p195 :017?> end
2.0.0p195 :018?> end
=> nil
2.0.0p195 :019 > a = A.new 3
=> #<A:0x000000026024b0 @a=3>
2.0.0p195 :022 > x = a.method :addition
=> #<Method: A#addition>
2.0.0p195 :023 > x.call 4
=> 7

You can also get an unbound method, but you can only call it after
binding it to an object of the same class (kind_of):

2.0.0p195 :026 > u = x.unbind
=> #<UnboundMethod: A#addition>
2.0.0p195 :027 > u.call 4
NoMethodError: undefined method `call’ for #<UnboundMethod: A#addition>

2.0.0p195 :028 > b = u.bind(A.new 12)
=> #<Method: A#addition>
2.0.0p195 :029 > b.call 4
=> 16

Hope this helps,

Jesus.

Its that easy. Wow, thank you. never heard of the method method :smiley:

Seems that the Method than works like a Proc? I guess that the only
difference is, that a Proc isnt bound to an object ^^

2014-06-30 18:11 GMT+02:00 Eric C.
[email protected]:

On Mon, Jun 30, 2014, Addis A. wrote:

Hiii,

Hi!

i am new to this ruby-talk list, so i hope my question is not annoying
(especially for my not so goood english).

Not at all. As you might have seen from other messages today, we’re
hungry for some actual Ruby discussion.

My question is simple. Is there a way to store a method in a variable? I
know that every method can be called with the keyword and send, but is
there a way to make it direct callable?

Yes. Functions and methods (they’re both the same construct really) can
be held in objects of the Method class, which are obtained by calling
obj.method(:method_name). Omit the receiver for functions/global
methods like puts.

Is there a method like partial or anything like this in ruby?
See this snippet:

def addition(a, b)
  a + b
end

x = method(:addition)
puts x.call(2, 3)
puts x[2, 3] # syntax sugar; however, note [] instead of ()

class Foo
  attr_accessor :a

  def initialize(a)
    self.a = a
  end

  def addition(b)
    self.a + b
  end
end

# For methods inside of classes:
f = Foo.new(2)
x = f.method(:addition)
puts x.call(3)
puts x[3]

On Tue, Jul 1, 2014 at 10:50 AM, Addis A. [email protected]
wrote:

Its that easy. Wow, thank you. never heard of the method method :smiley:

:slight_smile:

Seems that the Method than works like a Proc? I guess that the only
difference is, that a Proc isnt bound to an object ^^

A Proc is a closure which a method is not. A Method only catches self
i.e. the object which will receive the call. An UnboundMethod does
not even do that.

A closure captures variables from the surrounding scope

$ ruby -e ‘x = 9; f = lambda {|y| x + y};p f.call(7)’
16

… which can even be changed:

$ ruby -e ‘x = 9; f = lambda {|y| x + y};p f.call(7);x = 100; p
f.call(7)’
16
107

Kind regards

robert

Ohh, scope matters :slight_smile: Thank you for the hint ^^

This topic gives a new perspective for a lot ^^

2014-07-01 11:37 GMT+02:00 Robert K. [email protected]:

Is there a method like partial or anything like this in ruby?

Yes, Proc#curry():

p = Proc.new do |x, y, z|
x + y + z
end

new_p = p.curry[10, 20]
puts new_p[30]

–output:–
60