# Passing methods as parameters - the nice way?

**URL:** <https://www.ruby-forum.com/t/passing-methods-as-parameters-the-nice-way/118193>\
**Category:** Ruby\
**Created:** [October 24, 2007, 5:31pm UTC](https://www.ruby-forum.com/t/passing-methods-as-parameters-the-nice-way/118193 "2007-10-24T17:31:58Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![SSSSSren\_Andersen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/3ec8ea/32.png) [@SSSSSren\_Andersen](https://www.ruby-forum.com/u/SSSSSren_Andersen)\
**Post date:** [October 24, 2007, 5:31pm UTC](https://www.ruby-forum.com/t/passing-methods-as-parameters-the-nice-way/118193/1 "2007-10-24T17:31:58Z")

</div>

Hello all,

I’m pretty new to ruby, but have some background in Java, and very  
little  
C(++) and suchlike.  
I’m currently - as a “learning-by-doing”-project - creating a simple  
text-based interface for running (more or less) arbitrary programs.  
I decided on a simple tree-based structure for the menu itself, however  
I’m  
a bit stuck on the hook between my interface, and the program running  
behind  
it.

In order to not couple my interface too tightly to my program running  
behind  
it, I’d really like for my interface to not know what it’s actually  
interfacing with.  
Basically, I just figured I could take a leaf from the  
Functional-programming style and give my TextInterface a method to call  
when  
I told it to:  
def call\_action  
if(@action\_method)  
send(@action\_method)  
end  
end

which works fine, as long as my method is defined “in the wild”:

def foo  
puts “foo called”  
end

interface.set\_action(:foo)  
interface.call\_action =\> foo called

but, how do I handle it if the method is an instance method on some  
object?  
program = Program.new  
interface.set\_action(:program.foo)?  
No variant of this works for me.

I realise I may be fundamentally wrong in my approach, so any tips would  
be  
welcome. 🙂

Regards,

SÃ¸ren Andersen

---

<div class="post-metadata">

**Author:** ![SSSSSren\_Andersen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/3ec8ea/32.png) [@SSSSSren\_Andersen](https://www.ruby-forum.com/u/SSSSSren_Andersen)\
**Post date:** [October 24, 2007, 5:39pm UTC](https://www.ruby-forum.com/t/passing-methods-as-parameters-the-nice-way/118193/2 "2007-10-24T17:39:35Z")

</div>

On Oct 24, 6:31 pm, “Søren Andersen” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> interface.set\_action(:foo)  
> interface.call\_action =\> foo called
> 
> but, how do I handle it if the method is an instance method on some object?  
> program = Program.new  
> interface.set\_action(:program.foo)?  
> No variant of this works for me.

You should pass the target object to the interface as well, and then  
do “my\_obj.send(an\_instance\_method\_foo)”

---

<div class="post-metadata">

**Author:** ![SSSSSren\_Andersen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/3ec8ea/32.png) [@SSSSSren\_Andersen](https://www.ruby-forum.com/u/SSSSSren_Andersen)\
**Post date:** [October 24, 2007, 6:17pm UTC](https://www.ruby-forum.com/t/passing-methods-as-parameters-the-nice-way/118193/3 "2007-10-24T18:17:40Z")

</div>

Doh, ofc.

I should have figured that out myself.

Thank you!

Regards,

SÃ¸ren

---

<div class="post-metadata">

**Author:** ![SSSSSren\_Andersen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/3ec8ea/32.png) [@SSSSSren\_Andersen](https://www.ruby-forum.com/u/SSSSSren_Andersen)\
**Post date:** [October 24, 2007, 6:23pm UTC](https://www.ruby-forum.com/t/passing-methods-as-parameters-the-nice-way/118193/4 "2007-10-24T18:23:48Z")

</div>

SÃ¸ren Andersen wrote:

> Hello all,
> 
> I told it to:  
> def call\_action  
> if(@action\_method)  
> send(@action\_method)  
> end  
> end
> 
> which works fine, as long as my method is defined “in the wild”:
> 
> def foo  
> puts “foo called”  
> end
> 
> interface.set\_action(:foo)  
> interface.call\_action =\> foo called

I’d suggest using blocks instead of the above construct. Your code  
transformed:

def on\_action(&block)  
@action = block  
end

def action  
@action.call if @action  
end

obj = Object.new  
def obj.foo; puts “foo on #{self.inspect} called”; end

interface.on\_action { obj.foo }  
interface.action

# alternatively:

interface.on\_action(&obj.method(:foo))  
interface.action

Blocks are far more flexible than passing a method name or instance.

Regards  
Stefan

---

<div class="post-metadata">

**Author:** ![SSSSSren\_Andersen](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/3ec8ea/32.png) [@SSSSSren\_Andersen](https://www.ruby-forum.com/u/SSSSSren_Andersen)\
**Post date:** [October 26, 2007, 11:01pm UTC](https://www.ruby-forum.com/t/passing-methods-as-parameters-the-nice-way/118193/5 "2007-10-26T23:01:15Z")

</div>

On 10/24/07, Stefan R. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > 
> 
> transformed:  
> def obj.foo; puts “foo on #{self.inspect} called”; end  
> Regards  
> Stefan

Thanks! I’ll try this approach as well!

Regards,

SÃ¸ren
