From: Igor Pirnovar Date: 2009-04-06T03:10:56+09:00 Subject: Re: Function as Parameter? 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. -- Posted via http://www.ruby-forum.com/.