[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

function inside a function

Jason

1/28/2009 3:49:00 PM

I have a question about the timing of function evaluations in this case:

def function_a(x = 1)
x**2 + x
end

def function_b(any_function)
y = 4 + 5 #this would actually be more complex
function_a(y)
end

puts function_b(function_a)

I found that function_a(x = 1) is evaluated first, then
function_b(function_a). I found that 'def function_a(x = nil) returns an
error. Why does function_a need to be evaluated before it is called as
an argument in function_b?

PS - the reason I am writing things this way is to make function_b
accept any function (within reason).
--
Posted via http://www.ruby-....

4 Answers

Jesús Gabriel y Galán

1/28/2009 4:02:00 PM

0

On Wed, Jan 28, 2009 at 4:49 PM, Jason Lillywhite
<jason.lillywhite@gmail.com> wrote:
> I have a question about the timing of function evaluations in this case:
>
> def function_a(x = 1)
> x**2 + x
> end
>
> def function_b(any_function)
> y = 4 + 5 #this would actually be more complex
> function_a(y)
> end
>
> puts function_b(function_a)
>
> I found that function_a(x = 1) is evaluated first, then
> function_b(function_a). I found that 'def function_a(x = nil) returns an
> error. Why does function_a need to be evaluated before it is called as
> an argument in function_b?

The problem here is that when you write function_a, this is actually
*calling* function_a,which as you are not supplying any parameter uses
the default value of 1 you defined.

> PS - the reason I am writing things this way is to make function_b
> accept any function (within reason).

For sure there are many ways to achieve this, but a common way is to
use blocks and lambdas:

function_a = lambda {|x| x**2 + x}

def function_b
y = 4 + 5 #this would actually be more complex
yield y
end

or more explicitly:

def function_b (&blk)
y = 4 + 5
blk.call(y) # or blk[y]
end

puts function_b(&function_a)

Hope this helps,

Jesus.

Rubén Medellín

1/28/2009 4:44:00 PM

0

In ruby, function_a is a method call (with no arguments), and as a
call, it gets evaluated to whatever that function returns. If you
wanted to grab the function as a "pure function", you'd use lambdas or
Procs like Jesús pointed.

In other words:

function_a = Proc.new {|x| ..do something with x... }

returns a functional object. You can then call the method with
function_a.call (aliased [])

see http://www.ruby-doc.org/core/classes... for details on Proc
objects


Greetings

On Jan 28, 9:49 am, Jason Lillywhite <jason.lillywh...@gmail.com>
wrote:
> I have a question about the timing of function evaluations in this case:
>
> def function_a(x = 1)
>   x**2 + x
> end
>
> def function_b(any_function)
>   y = 4 + 5 #this would actually be more complex
>   function_a(y)
> end
>
> puts function_b(function_a)
>
> I found that function_a(x = 1) is evaluated first, then
> function_b(function_a). I found that 'def function_a(x = nil) returns an
> error. Why does function_a need to be evaluated before it is called as
> an argument in function_b?
>
> PS - the reason I am writing things this way is to make function_b
> accept any function (within reason).
> --
> Posted viahttp://www.ruby-....

Jason

1/28/2009 5:43:00 PM

0

Perfect. Thank you!
--
Posted via http://www.ruby-....

Brian Candler

1/28/2009 7:02:00 PM

0

Ruben Medellin wrote:
> In ruby, function_a is a method call (with no arguments), and as a
> call, it gets evaluated to whatever that function returns. If you
> wanted to grab the function as a "pure function", you'd use lambdas or
> Procs like Jes�s pointed.
>
> In other words:
>
> function_a = Proc.new {|x| ..do something with x... }
>
> returns a functional object. You can then call the method with
> function_a.call (aliased [])

Or, if you really want to do this with def'd methods, you can use

obj.method(:function_a)

which will turn an existing method (bound to the instance 'obj') into a
Proc-like thing that you can pass around and call later.

def function_a(x = 1)
x**2 + x
end

def function_b(any_function)
y = 4 + 5
any_function.call(y) # or: any_function[y]
end

puts function_b(method(:function_a))
--
Posted via http://www.ruby-....