I'm working in a new gem to extend the Ruby Core classes, something similar to Active Support Core Extensions or Powerpack. These days I'm working on the Proc class, for example I added closure composition.
But today I like to talk about currying. This is the Ruby standard library functionality for curry:
describe "#curry" do
it "returns a curried proc" do
modulus = ->(mod, num) { num % mod }
mod2 = modulus.curry[2]
expect(mod2.call(5)).to eq(1)
end
end
I like to add a new rcurry method to support proc "right" currying to pass the following spec. It's the same issue reported a few months ago, Proc/Method#rcurry working like curry but in reverse order.
describe "#rcurry" do
it "returns a right curried proc" do
modulus = ->(mod, num) { num % mod }
mod2 = modulus.rcurry[2]
expect(mod2.call(5)).to eq(2)
end
end
I think the way to solve this is to first solve an easier problem: How do we implement our owncurry?
One important thing you may or may not know is that Proc#[] is an alias for Proc#call, so in the above code modulus.curry[2] is the same as modulus.curry.call(2). Just for clarity I'm going to use .call in the code below.
Here's the first bit of code from your spec:
modulus = ->(mod, num) { num % mod }
mod2 = modulus.curry.call(2)
The second line tells us that modulus.curry returns a Proc (because we invoke call on it), so we know our method definition will look a bit like this:
class Proc
def curry_b
proc do |*passed|
# ???
end
end
end
Now when we call modulus.curry.call(2), the value of passed in the innermost block will be [ 2 ] (an array because we used the splat operator).
Here's the next part of your code:
mod2 = modulus.curry.call(2)
expect(mod2.call(5)).to eq(1)
Here we see that modulus.curry.call(2) itself returns a Proc, so now our method looks like this:
def curry_b
proc do |*passed|
proc do |*args|
# ??
end
end
end
Now when we call mod2.call(5), the value of args in the innermost block will be [ 5 ].
So we have [ 2 ] in passed and [ 5 ] in args. We want the return value of mod2.call(5) to be the same as the return value of modulus.call(2, 5)βin other words, modulus.call(*passed, *args). In our method , modulus is self, so we just have to do this:
def curry_b
proc do |*passed|
proc do |*args|
self.call(*passed, *args)
end
end
end
Now we can shorten it a bit and try it out:
class Proc
def curry_b
proc do |*passed|
proc {|*args| self[*passed, *args] }
end
end
end
mod2 = modulus.curry_b[2]
puts mod2.call(5)
# => 1
We've reimplemented curry! How, then, do we implement rcurry? Well, the only difference is that rcurry puts the curried arguments at the end instead of the beginning, so believe it or not we just have to switch passed and args around:
class Proc
def rcurry
proc do |*passed|
proc {|*args| self[*args, *passed] }
end
end
end
modulus = ->(mod, num) { num % mod }
mod2 = modulus.rcurry[2]
p mod2.call(5)
# => 2
Of course, this isn't perfect: Unlike Proc#curry curry_b and rcurry don't take an arity argument. That shouldn't be too tough, so I'll leave it as an exercise for you.
Related
I'm writing a simple method that adds num to the return value of the block that is passed to it and I noticed that &block and &prc both work. I know that a proc is an object and can be assigned to a variable which could be handy. Is that the only difference though? Is there any difference between these two when it comes to performance, convention, or versatility? Is it ever better to use &block instead of &prc?
def adder(num = 1, &block)
yield + num
end
vs.
def adder(num = 1, &prc)
yield + num
end
Is there any difference between these two when it comes to
performance, convention, or versatility?
There is no difference between these, you able to name it as you want, it's just a name. Some devs call it &blk some &block or &b or &foo ...
>> def foo &foo
>> yield
>> end
=> :foo
>> foo do
?> puts '1'
>> end
1
Strictly saying & is an operator which you can apply to any object, and it will take care of converting that object to a Proc by calling to_proc().
>> def bar(&some_proc)
>> some_proc
>> end
=> :bar
>> p = bar { puts 'Call proc' }
=> #<Proc:0x005601e6d69c80#(irb):4>
>> p.call
=> Call proc
>> p.class
=> Proc
Only the one thing is important, the name should be informative.
Line any argument to your method the name is largely subjective. Typically you'll see &block used if only by convention, but the name itself can be anything you want so long as it's a valid variable name.
In your example you're declaring a block name but not actually using the name. Keep in mind that any Ruby method can be given a block, there's no way to restrict this, but it's up to the method itself to use the block if it wants. That block can be called zero or more times either immediately or at some point in the future. Giving the block to the method surrenders control, so be sure to read the documentation on any given method carefully. There can be surprises.
If you need to chain through a block, declare it with a name:
def passes_through(&block)
[ 1, 2, 3, 4 ].each(&block)
end
If you are going to yield on the block there's no need here:
def direct_call
[ 1, 2, 3, 4 ].each do |n|
yield n
end
end
If you're going to preserve the call and use it later, that's also a case for naming it:
def preserved_call(&block)
#callback = block
end
def make_callback
#callback and #callback.call
end
Any method can check if a block was supplied:
def tests_for_block
if (block_given?)
yield 'value'
else
'value'
end
end
There's a small but measurable cost to capturing a block by declaring it in the method signature, a lot of computation has to be done to properly capture all the variables that might be used in a closure situation. In performance sensitive code you'll want to avoid this.
You can dynamically create a block:
def captures_conditionally
if (block_given?)
#callback = Proc.new
end
end
The Proc.new method will assume control over whatever block has been supplied to the method if one has been.
in your example, there is not a difference between &block and &prc, because in each case you are just passing a block to be call into the method.
Block and proc are similar in that they are both blocks of code.
[1,2,3].each {|x| puts x }
everything within the {} is the block.
A proc is just a block of code that you can name and can be called at a later time.
put_element = Proc.new {|x| puts x}
then you use put_element as an argument in your function.
I want to be able to call a function this way:
func = ->(a, b) {
if ...
method1 # error - it requires 2 arguments when it's being called
# it should be method1(a, b)
# but I don't want that redundancy here
elsif ...
method2 # error - it requires 2 arguments when it's being called
elsif ...
method3 # error - it requires 2 arguments when it's being called
else ...
method4 # error - it requires 2 arguments when it's being called
end
}
param1 = ....
param2 = ....
func.call(param1, param2) # ok so far but error in the block above
def method1(var1, var2)
end
def method2(var1, var2)
end
def method3(var1, var2)
end
def method4(var1, var2)
end
But I don't want to repeat myself inside the block func = ->(a, b) { by adding 2 arguments to the functions. Those of you who know Haskell will understand what I mean.
Is there any way to do it?
You can store the name of the method you want to call as a string-variable (or symbol); then use send to pass this variable along with the arguments.
An example:
def method_one(a, b)
# something_one
end
def method_two(a, b)
# something_two
end
def method_three(a, b) # the method you call
if condition_one
method_name = "method_one"
elsif condition_two
method_name = "method_two"
else
# something else
end
send(method_name, a, b) if method_name
end
If method_one and method_two are public methods, I would recommend using public_send instead of send simply because it is more explicit which could potentially help others who read your code.
From the Haskell wiki: "Currying is the process of transforming a function that takes multiple arguments into a function that takes just a single argument and returns another function if any arguments are still needed."
OP does not provide a single argument, but no arguments at all. Anyway, Ruby does have a curry method which results in a proc:
proc1 = ->(var1,var2){p var1+var2}.curry
proc2 = proc1[1] #same as proc2 = proc1.call(1)
proc2[2] # => 3
Asking for clarification here since this isn't going to fit in a comment:
My understanding of currying:
method_one(a, b) takes two arguments.
If you call it using method_one(a), it should return a partial function which expects one argument, and applies the first to the second. Eg.
def multiply(a, b=nil)
if b
a*b
else
Proc.new { |b| a*b }
end
end
This allows you to do stuff like:
def multiply_by_three(b)
multiply(3).call
end
So do you want to:
pass in a and b to func and get back a Proc acting on a and b or,
define your separate methods outside and apply it inside func without using the method_name(a,b) form?
I have this code:
l = lambda { a }
def some_function
a = 1
end
I just want to access a by the lambda and a special scope which has defined a already somewhere like inside some_function in the example, or just soon later in the same scope as:
l = lambda { a }
a = 1
l.call
Then I found when calling l, it is still using its own binding but not the new one where it was called.
And then I tried to use it as:
l.instance_eval do
a = 1
call
end
But this also failed, it is strange that I can't explain why.
I know the one of the solution is using eval, in which I could special a binding and executing some code in text, but I really do not want to use as so.
And, I know it is able to use a global variable or instance variable. However, actually my code is in a deeper embedded environment, so I don't want to break the completed parts if not quite necessary.
I have referred the Proc class in the documentation, and I found a function names binding that referred to the Proc's context. While the function only provided a way to access its binding but cannot change it, except using Binding#eval. It evaluate text also, which is exactly what I don't like to do.
Now the question is, do I have a better (or more elegant) way to implement this? Or using eval is already the regular manner?
Edit to reply to #Andrew:
Okay, this is a problem which I met when I'm writing a lexical parser, in which I defined a array with fixed-number of items, there including at least a Proc and a regular expression. My purpose is to matching the regular expressions and execute the Procs under my special scope, where the Proce will involved some local variables that should be defined later. And then I met the problem above.
Actually I suppose it is not same completely to that question, as mine is how to pass in binding to a Proc rather than how to pass it out.
#Niklas:
Got your answer, I think that is what exactly I want. It has solved my problem perfectly.
You can try the following hack:
class Proc
def call_with_vars(vars, *args)
Struct.new(*vars.keys).new(*vars.values).instance_exec(*args, &self)
end
end
To be used like this:
irb(main):001:0* lambda { foo }.call_with_vars(:foo => 3)
=> 3
irb(main):002:0> lambda { |a| foo + a }.call_with_vars({:foo => 3}, 1)
=> 4
This is not a very general solution, though. It would be better if we could give it Binding instance instead of a Hash and do the following:
l = lambda { |a| foo + a }
foo = 3
l.call_with_binding(binding, 1) # => 4
Using the following, more complex hack, this exact behaviour can be achieved:
class LookupStack
def initialize(bindings = [])
#bindings = bindings
end
def method_missing(m, *args)
#bindings.reverse_each do |bind|
begin
method = eval("method(%s)" % m.inspect, bind)
rescue NameError
else
return method.call(*args)
end
begin
value = eval(m.to_s, bind)
return value
rescue NameError
end
end
raise NoMethodError
end
def push_binding(bind)
#bindings.push bind
end
def push_instance(obj)
#bindings.push obj.instance_eval { binding }
end
def push_hash(vars)
push_instance Struct.new(*vars.keys).new(*vars.values)
end
def run_proc(p, *args)
instance_exec(*args, &p)
end
end
class Proc
def call_with_binding(bind, *args)
LookupStack.new([bind]).run_proc(self, *args)
end
end
Basically we define ourselves a manual name lookup stack and instance_exec our proc against it. This is a very flexible mechanism. It not only enables the implementation of call_with_binding, it can also be used to build up much more complex lookup chains:
l = lambda { |a| local + func(2) + some_method(1) + var + a }
local = 1
def func(x) x end
class Foo < Struct.new(:add)
def some_method(x) x + add end
end
stack = LookupStack.new
stack.push_binding(binding)
stack.push_instance(Foo.new(2))
stack.push_hash(:var => 4)
p stack.run_proc(l, 5)
This prints 15, as expected :)
UPDATE: Code is now also available at Github. I use this for one my projects too now.
class Proc
def call_with_obj(obj, *args)
m = nil
p = self
Object.class_eval do
define_method :a_temp_method_name, &p
m = instance_method :a_temp_method_name; remove_method :a_temp_method_name
end
m.bind(obj).call(*args)
end
end
And then use it as:
class Foo
def bar
"bar"
end
end
p = Proc.new { bar }
bar = "baz"
p.call_with_obj(self) # => baz
p.call_with_obj(Foo.new) # => bar
Perhaps you don't actually need to define a later, but instead only need to set it later.
Or (as below), perhaps you don't actually need a to be a local variable (which itself references an array). Instead, perhaps you can usefully employ a class variable, such as ##a. This works for me, by printing "1":
class SomeClass
def l
#l ||= lambda { puts ##a }
end
def some_function
##a = 1
l.call
end
end
SomeClass.new.some_function
a similar way:
class Context
attr_reader :_previous, :_arguments
def initialize(_previous, _arguments)
#_previous = _previous
#_arguments = _arguments
end
end
def _code_def(_previous, _arguments = [], &_block)
define_method("_code_#{_previous}") do |_method_previous, _method_arguments = []|
Context.new(_method_previous, _method_arguments).instance_eval(&_block)
end
end
_code_def('something') do
puts _previous
puts _arguments
end
I want to have a method defined on Object that takes a block and applies the receiver to the block. An implementation will be like the following:
class Object
def apply ≺ pr.call(self) end
end
2.apply{|x| x * 3} # => 6
Is there already a standard way to do this or a well known library that has a method with similar use? If so, I didn't want to reinvent the wheel.
It happens to me very often that, I have a method that takes an optional block, and when there is no block, I want to return some return_value calculated within the method, but when there is a block, I want to return the return value of the return_value applied to the block. For now, I have bunches of lines like:
def method ..., &pr
...
pr ? pr.call(return_value) : return_value
end
but I want to consistently write
def method ..., &pr
...
pr ? return_value.apply(&pr) : return_value
end
or even better, with a slightly modified definition of apply,
def method ..., &pr
...
return_value.apply(&pr)
end
I guess Object.tap is what you are looking for:
"Abc".tap do |str|
puts str
end
Is that not identical to def apply; yield self; end? β steenslag
#steenslag Yes. It is. I want to have that effect with self as the receiver. β sawa
Is this what you mean?
2.instance_eval { * 3 }
# => 6
Unfortunately, that doesn't work. instance_eval simply runs code as if the receiver was self. Operators don't presume self as the receiver, so you'd actually have to write this:
2.instance_eval { self * 3 }
# => 6
However, as a proof of concept, this is possible:
Numeric.send(:define_method, :plus) { |x| self + x }
2.instance_eval { plus 3 }
# => 5
(Aftwer reading OP's edit) AFAIK the canonical way to write this is:
def purpose(*args) #no &bl or &pr
res = 42 #huge calculation
return res unless block_given?
yield res
end
p purpose(1,2)
purpose{|n| puts "from the block: #{n}"}
I'd like to write a method that yields values in one place and pass it as a parameter to another method that will invoke it with a block. I'm convinced it can be done but somehow I'm not able to find the right syntax.
Here's some sample (non-working) code to illustrate what I'm trying to achieve:
def yielder
yield 1
yield 2
yield 3
end
def user(block)
block.call { |x| puts x }
end
# later...
user(&yielder)
$ ruby x.rb
x.rb:2:in `yielder': no block given (yield) (LocalJumpError)
from x.rb:12:in `<main>'
FWIW, in my real code, yielder and user are in different classes.
Update
Thanks for your answers. As Andrew Grimm mentioned, I want the iterator method to take parameters. My original example left this detail out. This snippet provides an iterator that counts up to a given number. To make it work, I made the inner block explicit. It does what I want, but it's a bit ugly. If anyone can improve on this I'd be very interested in seeing how.
def make_iter(upto)
def iter(upto, block)
(1 .. upto).each do |v|
block.call(v)
end
end
lambda { |block| iter(upto, block) }
end
def user(obj)
obj.call Proc.new { |x| puts x }
end
# later...
user(make_iter(3))
This doesn't use a lambda or unbound method, but it is the simplest way to go...
def f
yield 1
yield 2
end
def g x
send x do |n|
p n
end
end
g :f
When you write &yielder, you're calling yielder and then trying to apply the & (convert-to-Proc) operator on the result. Of course, calling yielder without a block is a no-go. What you want is to get a reference to the method itself. Just change that line to user(method :yielder) and it will work.
I think this might be along the lines of what you want to do:
def yielder
yield 1
yield 2
yield 3
end
def user(meth)
meth.call { |x| puts x }
end
# later...
user( Object.method(:yielder) )
Some related info here: http://blog.sidu.in/2007/11/ruby-blocks-gotchas.html
As it has been pointed out the baseline problem is that when you try to pass a function as a parameter Ruby executes it β as a side effect of parenthesis being optional.
I liked the simplicity of the symbol method that was mentioned before, but I would be afraid of my future self forgetting that one needs to pass the iterator as a symbol to make that work. Being readability a desired feature, you may then wrap your iterator into an object, which you can pass around without fear of having code unexpectedly executed.
Anonymous object as iterator
That is: using an anonymous object with just one fuction as iterator. Pretty immediate to read and understand. But due to the restrictions in the way Ruby handles scope the iterator cannot easily receive parameters: any parameters received in the function iterator are not automatically available within each.
def iterator
def each
yield("Value 1")
yield("Value 2")
yield("Value 3")
end
end
def iterate(my_iterator)
my_iterator.each do |value|
puts value
end
end
iterate iterator
Proc object as iterator
Using a Proc object as iterator lets you easily use any variables passed to the iterator constructor. The dark side: this starts looking weird. Reading the Proc.new block is not immediate for the untrained eye. Also: not being able to use yield makes it a bit uglier IMHO.
def iterator(prefix:)
Proc.new { |&block|
block.call("#{prefix} Value 1")
block.call("#{prefix} Value 2")
block.call("#{prefix} Value 3")
}
end
def iterate(my_iterator)
my_iterator.call do |value|
puts value
end
end
iterate iterator(prefix: 'The')
Lambda as iterator
Ideal if you want to obfuscate your code so hard that no one else besides you can read it.
def iterator(prefix:)
-> (&block) {
block.call("#{prefix} Value 1")
block.call("#{prefix} Value 2")
block.call("#{prefix} Value 3")
}
end
def iterate(my_iterator)
my_iterator.call do |value|
puts value
end
end
iterate iterator(prefix: 'The')
Class as iterator
And finally the good ol' OOP approach. A bit verbose to initialize for my taste, but with little or none surprise effect.
class Iterator
def initialize(prefix:)
#prefix = prefix
end
def each
yield("#{#prefix} Value 1")
yield("#{#prefix} Value 2")
yield("#{#prefix} Value 3")
end
end
def iterate(my_iterator)
my_iterator.each do |value|
puts value
end
end
iterate Iterator.new(prefix: 'The')