Passing Functions as Arguments

I’ve only been programming in Ruby for a few days (so be gentle), but I
wrote the beginning of an object that could do numerical approximations
of Differential Equations, below, as well as a simple test to see if the
function works (it’s the ODE y’ - y = 0). However, I’m not sure how to
pass functions as instance variables in Ruby. Any help here? (I’m sure
there’s already a gem that does DE approximations, I’m just practicing!)

The problem is that when I use .call on @function, I get an error saying
that I’ve supplied 0 of 2 arguments needed for the function. I’m not
sure why this happens.

class EulerDE

def initialize(x0, y0, function)
@x = x0
@y = y0
@function = function
end

def eulermethod(h, max)
count = 1
puts “#{count}) x = #{@x}, y = #{@y}”
while count < 10
x = @x + h
y = @y
y = @y + h * @function.call(x, y)
count += 1
puts “#{count}) x = #{@x}, y = #{@y}”
end
end

end

def func(x,y)
y
end

de = EulerDE.new(0, 1, &func)

de.eulermethod(0.03, 10)

When you write “&func”, it isn’t treated as a 3rd argument, it’s passed
separately as a block.

Instead, try this:

func = -> (x,y) {y}

de = EulerDE.new(0, 1, func)

What does the -> arrow mean in this context?

This is a shortcut; it should be equal to lambda.

You can invoke .call on such objects then.

Using Lambdas worked like a charm.

A nice shortcut I learnt on code-golf is that you can use [] on lambdas
to call them, this gets rid of ugly .call calls.

f(x) = x^2, g(x) = x+5, h(x,a,b) = a(b(x))

f = ->x{x**2}
g = ->x{x+5}
h = ->x,a,b{a[b[x]]}

puts f[5]
puts h[3,f,g]
puts h[3,g,f]
p (1…10).map(&f)