CSC/ECE 517 Fall 2007/wiki1 2 316

From Expertiza_Wiki
Revision as of 00:26, 15 September 2007 by Tmakhij (talk | contribs)
Jump to navigation Jump to search

The Question

A callback is code that one wants to be called from within a method after that method has been called. That is, it is a method of the caller that is invoked by the callee. Give an example using a closure in Ruby, and show how this is more elegant than similar code in Smalltalk.

Understanding of the question

The question requires us to compare callback using a closure code constructed in RUBY with a similar code constructed in Smalltalk and then show how the RUBY code is more elegant.

Approach

Suppose we need to associate actions to a particular button so that it does a required function. Eg. In a form if we press CLEAR, it should clear the form and SUBMIT should submit the form. Ruby’s blocks are a convenient way to do this. We assume that on pressing the button a callback method, button_pressed, will be invoked. The obvious way of adding functionality to these buttons is to create subclasses of Button(which is the class) and have each subclass implement its own button_pressed method. Eg.

class FormButton < Button
    def initialize
        super("Submit") # invoke Button's initialize
       end
   def button_pressed
   # do submit actions...
   end

end submit_button = FormButton.new This will lead to a large number of subclasses. We can fix this problem using blocks in RUBY. pressbutton = PressButton.new

  class FormButton < Button
    def initialize(label, &action)
       super(label)
       @action = action
    end
    def button_pressed
      @action.call(self)
    end
 end

submit_button = FormButton.new("Submit") { pressbutton.submit } reset_button = FormButton.new("Clear") { pressbutton.reset }

The key to all this is the second parameter to FormButton#initialize. If the last parameter in a method definition is prefixed with an ampersand (such as &action), Ruby looks for a code block whenever that method is called. That code block is converted to an object of class Proc and assigned to the parameter. You can then treat the parameter as any other variable. When the callback method button_pressed is invoked, we use the Proc#call method on that object to invoke the block.

Now if we want to do the same task in Smalltalk,