tags:

views:

62

answers:

2

I have this working code:

class Server
  def handle(&block)
    @block = block
  end

 def do
   @block.call
 end
end

class Client
  def initialize
    @server = Server.new
    @server.handle { action }
  end

  def action
    puts "some"
  end

  def call_server
    @server.do
  end
end

client = Client.new
client.call_server

My Server will handle more then one action so I want to change code such way:

class Server
  def handle(options)
    @block = options[:on_filter]
 end

 def do
   @block.call
 end
end

class Client
  def initialize
    @server = Server.new

   my_hash = { :on_filter => action }
   @server.handle(my_hash)
  end

  def action
    puts "some"
  end

  def call_server
    @server.do
  end
end

client = Client.new
client.call_server

It is incorrect code because action() method calls on create my_hash, but if I try to modify code to:

my_hash = { :on_filter => { action } }

i get error message.

Is it possible to create hash with methods as hash values ?

A: 

Sure it's possible, but not exactly with methods (as methods aren't objects in Ruby), but with Proc objects instead. Take a look at this tutorial, for example.

In short, you should be able to achieve what you want by

my_hash = { :on_filter => Proc.new{action} }

in your Client#initialize.

Mladen Jablanović
Methods sure are objects, they have a whole class for them! Actually, two of them: Method, UnboundMethod. Check my answer
Marc-André Lafortune
Hmm, not sure about that: http://www.mentby.com/david-a-black/are-methods-objects.html But you're right, `method` method can be useful as well.
Mladen Jablanović
He states that they are not "first class object", whatever that means. He might have a definition for that, but I don't.The argument with `object_id` simply shows that methods are not immediates (like symbols, true, ...). But neither are floats, strings, Procs, etc...Methods can be seen as an UnboundMethod with a bound receiver. That doesn't make them less of an object. In Ruby: `42.method(:to_s).is_a?(Object) # => true`
Marc-André Lafortune
I just think that the fact that an object is an instance of class `Method` doesn't make it a method. :) One can say that it's a method wrapped, or a method referenced, but not a method itself.
Mladen Jablanović
I took the liberty to open a question, as this intrigues me a lot, I hope you don't mind: http://stackoverflow.com/questions/2602340/methods-in-ruby-objects-or-not
Mladen Jablanović
+1  A: 

When you want a method, in Ruby, you have to call... method :-)

my_hash = { :on_filter => { method(:action) } }

Note that your original code could have been written:

@server.handle(&method(:action))

This tells it to use the method action as the block parameter (which is why there is a &). Instead, you were passing a block, so to be completely equivalent, you can now pass a block instead of a method if you prefer:

my_hash = { :on_filter => Proc.new{ action } }
Marc-André Lafortune