Creating callable variants of functions by currying in Ruby - code snippet showing how to avoid scope problems
While coding a project in Ruby, I was creating some variants of a function by currying. Initially, I simply created the curried variants as variables, but quickly ran into scope problems where I couldn't then call any of the variants from within other functions. This was because the scope of the variant was the same as the scope of a local variable of that name.
So I created a code snippet as a demo for myself of what I should have done instead, which is to define the curried variant as another function. This new function then has the same scope as any function I would create and not the (more limited) scope of a local variable.
Of course, in certain situations defining it as a local variable is more desirable - for example if I was instead planning to use the variant as a variable that could be passed around. This is as opposed to using it solely as a callable function, which is what I ultimately desired.
def myfun(stuff, num1, num2)
if stuff == true then
num1 + num2
else
num1 - num2
end
end
def myfun1
self.method(:myfun).curry.(true, 1)
end
myfun_false = self.method(:myfun).curry.(false)
# but the problem is that myfun_false has a scope that's only valid here
# so it can't be used within another function. This is a huge problem for
# the use case where it's designed to be called elsewhere, which is the
# majority of my use cases.
# It may be less of an issue for the situation where the intent is to
# pass the curried function itself around as a variable, instead
# of actually calling it.
puts myfun_false.(20, 18)
# 2
# By contrast, myfun1 can be called anywhere - here, or within another function.
# Remember that any function resulting from a curried function should be
# called via .call or just the syntactic sugar of '.' Both are illustrated
# below
puts myfun1.(12)
# 13
puts myfun1.call(18)
# 19
Above is the code snippet to remind myself of what *I* generally want to do, which is the approach taken in the myfun1 function. The other approach, myfun_false which results in a local variable, is also shown for comparison's sake.