# Function as Parameter?

**URL:** <https://www.ruby-forum.com/t/function-as-parameter/164729>\
**Category:** Ruby\
**Created:** [April 4, 2009, 9:03pm UTC](https://www.ruby-forum.com/t/function-as-parameter/164729 "2009-04-04T21:03:08Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![tomast](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/bc79bd/32.png) [@tomast](https://www.ruby-forum.com/u/tomast)\
**Post date:** [April 4, 2009, 9:03pm UTC](https://www.ruby-forum.com/t/function-as-parameter/164729/1 "2009-04-04T21:03:08Z")

</div>

I am new to Ruby so I don’t know a great deal about the language, but  
what I am trying to do is the following:  
Create an application that will display a login form. The user enters  
their details and then that form disappears and they are taken to a  
different form containing a canvas (which will have images drawn on it  
eventually).

I don’t want to create both forms and set their visibility, as the  
invisible form will still be loaded in memory which is a waste. They I  
thought of getting around this is to start the program in a “form  
manager” style class, which then has the ability to create either of the  
two forms. The trouble I am facing then, is that the button the form has  
to pass back the username and password to the form manager, so that when  
the Login form closes it may construct a Canvas from and pass the  
details.

To make this happen I figured I would pass in a callback. Searching  
around, I couldn’t find a lot of info about callbacks, but I was reading  
about passing a symbol. I may have got this wrong, but it looks like if  
I pass in :function\_name then it will be a symbol that I can call.

Well I tried it like this:

def TestFunc()  
puts ‘Test’  
end

xaApp = FXApp.new  
LoginForm.new(xaApp,‘TestApp’,:TestCallback)  
xaApp.create  
xaApp.run

In my “Form Manager”, and in my LoginForm’s initialize I have:  
def initialize(anApp,sTitle,aCallback)  
super(anApp, sTitle,:opts =\> DECOR\_ALL, :width =\> 165, :height =\>  
250)

```
FXLabel.new(self,"Username:", nil, JUSTIFY_LEFT|LAYOUT_FILL_X)
FXTextField.new(self, 23, nil, 0, TEXTFIELD_NORMAL)

FXLabel.new(self,"Password:", nil, JUSTIFY_LEFT|LAYOUT_FILL_X)
FXTextField.new(self, 23, nil, 0, TEXTFIELD_NORMAL)

xbButton = FXButton.new(self,"Log in",:opts =>

```

FRAME\_RAISED|LAYOUT\_CENTER\_X|LAYOUT\_FIX\_WIDTH|LAYOUT\_FIX\_HEIGHT,:width  
=\> 80, :height =\> 20)  
xbButton.connect(SEL\_COMMAND,aCallback)  
end

This runs okay until I click the button, at which point I get the error:  
C:\Users\Tomas\Desktop\Ruby\>ruby testapp.rb  
c:/ruby/lib/ruby/gems/1.8/gems/fxruby-1.6.12-mswin32/lib/fox16/responder2.rb:55:  
in `onHandleMsg': undefined method`call’ for :TestCallback:Symbol  
(NoMethodErro  
r)  
from testapp.rb:14:in `run’  
from testapp.rb:14

If I can get this working, then I will be able to move on to trying to  
get it working with passing the two string parameters in as well. Can  
someone please explain to me how I can call the function in my main code  
when the button is clicked in the form?

---

<div class="post-metadata">

**Author:** ![tomast](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/bc79bd/32.png) [@tomast](https://www.ruby-forum.com/u/tomast)\
**Post date:** [April 4, 2009, 9:12pm UTC](https://www.ruby-forum.com/t/function-as-parameter/164729/2 "2009-04-04T21:12:06Z")

</div>

Tomas Na wrote:

> C:\Users\Tomas\Desktop\Ruby\>ruby testapp.rb  
> c:/ruby/lib/ruby/gems/1.8/gems/fxruby-1.6.12-mswin32/lib/fox16/responder2.rb:55:  
> in `onHandleMsg': undefined method`call’ for :TestCallback:Symbol  
> (NoMethodErro  
> r)  
> from testapp.rb:14:in `run’  
> from testapp.rb:14

Sorry, the error is:  
c:/ruby/lib/ruby/gems/1.8/gems/fxruby-1.6.12-mswin32/lib/fox16/responder2.rb:55:  
in `onHandleMsg': undefined method`call’ for :TestFunc:Symbol  
(NoMethodError)  
from testapp.rb:14:in `run’  
from testapp.rb:14

The top one says :TestCallback because that is what it was called  
originally but I changed the name when I posted it here to make it a bit  
clearer, forgot to rerun to get the error with proper function name.

---

<div class="post-metadata">

**Author:** ![tomast](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/bc79bd/32.png) [@tomast](https://www.ruby-forum.com/u/tomast)\
**Post date:** [April 5, 2009, 5:45pm UTC](https://www.ruby-forum.com/t/function-as-parameter/164729/3 "2009-04-05T17:45:50Z")

</div>

On Saturday 04 April 2009 14:02:45 Tomas Na wrote:

> I am new to Ruby so I don’t know a great deal about the language, but  
> what I am trying to do is the following:  
> [snip]  
> To make this happen I figured I would pass in a callback. Searching  
> around, I couldn’t find a lot of info about callbacks,

Search for blocks.

Your example would probably be written something like this:

LoginForm.new(xaApp,‘TestApp’) do |arg1, arg2|  
callback logic goes here  
end

You may end up just calling a function inside that block, and that’s  
fine. But  
the idiomatic way is likely to provide a block. If you need to pass more  
than  
one such “callback”, you can pass proc objects, but that’s often slower  
and  
definitely more annoying for whoever uses that class.

---

<div class="post-metadata">

**Author:** ![tomast](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/bc79bd/32.png) [@tomast](https://www.ruby-forum.com/u/tomast)\
**Post date:** [April 5, 2009, 8:32pm UTC](https://www.ruby-forum.com/t/function-as-parameter/164729/4 "2009-04-05T20:32:38Z")

</div>

Sorry, the in the above TestFunc {{ var }} is out of scope. I just  
wanted to emphasize the fact that Method objects are not closures.

Following is the correction

def TestFunc()  
puts ‘Test’  
end  
…  
var = “this time not seen in my\_fu\_obj”  
my\_fu\_obj = method(:TestFunc)  
LoginForm.new(xaApp,‘TestApp’, my\_fu\_obj)

---

<div class="post-metadata">

**Author:** ![tomast](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/bc79bd/32.png) [@tomast](https://www.ruby-forum.com/u/tomast)\
**Post date:** [April 5, 2009, 8:11pm UTC](https://www.ruby-forum.com/t/function-as-parameter/164729/5 "2009-04-05T20:11:37Z")

</div>

Tomas Na wrote:

> To make this happen I figured I would pass in a callback.  
> Searching around, I couldn’t find a lot of info about  
> callbacks, but I was reading about passing a symbol. I may  
> have got this wrong, but it looks like if I pass in  
> :function\_name then it will be a symbol that I can call.

Symbol is not really what you think. It is merely a special code/name  
for “defined data” items (classes, variables and methods (or functions  
as you refer to them)) which are stored in Ruby’s symbol table. As such,  
namely as names, symbols are just like strings, they only are much more  
efficiently handled by Ruby than strings. To distinguish between a  
defined ruby item and its symbol the colon (🙂 is used before the name.  
Passing a symbol of a method (function) around is just like passing its  
name in the string form.

In order to execute a command as a string or a symbol you can use the {{  
method }} method.

def my\_test  
puts “in my\_test function”  
end  
puts :my\_test # -\> my\_test  
method(:my\_test).call # -\> in my\_test function  
method(“my\_test”).call # -\> in my\_test function  
var = “scope of creation”  
test\_fu\_lambda = lambda { puts ‘Test: %s’ % [var] }  
test\_fu\_lambda.call # -\> Test: scope of creation

Another way to pass a symbol to an iterator as an executable block is by  
preceding it with the ampersand (&), which effectively converts the  
method represented by the symbol to a proc! In Ruby, executable code is  
passed around in procs, lambdas and Method objects. There is no such  
thing as a function (method) pointer in Ruby. However a subtle  
differences between these objects of executable code exist, and you  
should learn about them. Especially you should know about the  
differences between procs and lambdas. The most important differences  
are in the way these executable objects are called (invoked) and the way  
their respective {{ return }} mechanisms behave. In general procs use {{  
yield }} invocation semantics but lambdas use the method invocation  
semantics. Hence, procs are associated with block behaviour, whereas  
lambdas are closer to method (function) behaviour.

Yet another important thing to understand is that procs and lambdas are  
closures, but method objects are not. Closures are important because  
they encapsulate in them all variables from the scope in which they are  
defined, which remain intact even when a proc or a lambda is executed in  
a totally different scope.

You can not expect to learn all you need to know about this from a  
single post on a forum, however, for you to continue working on your  
program it should suffice to know that you need to convert a method  
(function) you wish to pass to your LoginForm object to a lambda, and in  
it, that is in LoginForm object, invoke it with the {{ call }} method  
the i.e.; something like {{ test\_fu\_lambda.call }} as you have seen in  
the example above.

If {{ LoginForm }} is your own class you created, you need to change the  
invocation of your test function so it utilizes the {{ call }} method as  
shown above. Try the following:

var = “I am a variable from the scope where test\_fu\_lambda was  
created”  
test\_fu\_lambda = lambda { puts ‘Test: %s’ % [var] }  
LoginForm.new(xaApp,‘TestApp’, test\_fu\_lambda)

Alternatively you can create a Method object of any of your methods and  
pass it in instead. However, in this case your Method object will not  
hold on to the variables from the scope in which it is defined:

def TestFunc()  
puts ‘Test: %s’ % [var]  
end  
…  
var = “this time not seen in my\_fu\_obj”  
my\_fu\_obj = method(:TestFunc)  
LoginForm.new(xaApp,‘TestApp’, my\_fu\_obj)

In both cases you have to change the invocation of the executable  
objects you are passing to your {{ LoginForm }} to utilize the {{ \*.call  
}} syntax.

Indeed, what David wrote is the Ruby way of doing things, but sometimes  
converting methods or blocks to executable objects is more appropriate.
