# Pointer to function

**URL:** <https://www.ruby-forum.com/t/pointer-to-function/90042>\
**Category:** Ruby\
**Created:** [March 25, 2007, 2:11pm UTC](https://www.ruby-forum.com/t/pointer-to-function/90042 "2007-03-25T14:11:07Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![ekkehard.horner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/c2a13f/32.png) [@ekkehard.horner](https://www.ruby-forum.com/u/ekkehard.horner)\
**Post date:** [March 25, 2007, 2:11pm UTC](https://www.ruby-forum.com/t/pointer-to-function/90042/1 "2007-03-25T14:11:07Z")

</div>

Just starting to learn Ruby, I’d like to ask if somebody would be so  
kind as to help me ‘translate’ this Perl proof of concept code:

```
 package cApp;
 # POC application class that can run named Fncs via 'pointer to 

```

function’

```
 my %Fncs = ( 'frsFnc' => ['just tell "frsFnc"', \&frsFnc]
              , 'secFnc' => ['just tell "secFnc"', \&secFnc]
            );

 sub new
 { my $class = shift;

   my $self = { name => shift
                 , Fncs => \%Fncs
               };
   bless( $self, $class );
 }

 sub run
 { my $self = shift;
   my $sFnc = shift;
   if( exists( $self->{ Fncs }->{ $sFnc } ) )
     { &{$self->{ Fncs }->{ $sFnc }->[1]}( $self )
     }
   else
     { print "no '$sFnc' in: ", join( ' ', keys( %{$self->{ Fncs }} 

```

) ), “\n”;  
}  
}

```
 sub frsFnc
 { my $self = shift;
   print $self->{ name }, '::frsFnc', "\n";
 }

 sub secFnc
 { my $self = shift;
   print $self->{ name }, '::secFnc', "\n";
 }

 package main;
 # main: create instance of cApp, get Fnc name, run named Fnc

 my $oApp = cApp->new( 'trivial' );
 my $sFnc = $ARGV[0] || 'frsFnc';
 $oApp->run( $sFnc );

```

to Ruby. That’s what I have now:

```
 class CAPP

   @name = 'anonym'
   @Fncs = nil

   def to_s
     'POC application class that can run named Fncs via "pointer to 

```

function"’  
end

```
   def initialize( name )
     @name = name
     @Fncs = { 'frsFnc' => ['just tell "frsFnc"', nil] ,
               'secFnc' => ['just tell "secFnc"', nil]
             }
   end

   def run( sFnc )
     puts @name + '::run( "' + sFnc + '" )'
     if @Fncs.has_key?( sFnc )
        puts "can't call fnc by name yet"
     else
        puts 'no ' + sFnc + ' in: ' + @Fncs.keys.join( ' ' )
     end
   end

   def frsFnc
     puts @name + '::frsFnc'
   end

   def secFnc
     puts @name + '::secFnc'
   end

 end # class CAPP

 # main: create instance of cApp, get Fnc name, run named Fnc

 oApp = CAPP.new( 'trivial' )
 puts oApp.to_s

 puts "That's easy:"
 oApp.frsFnc()
 oApp.secFnc()

 sFnc = ARGV[0] || 'frsFnc'
 puts "Now call " + sFnc + ', please:'

 oApp.run( sFnc )

```

Is it possible to replace the “nil” in @Fncs and the  
puts “can’t call fnc by name yet”  
in run() with suitable Ruby expressions/statements?

I looked at lamba, but I don’t want to define the functions using  
strings.

Thanks

---

<div class="post-metadata">

**Author:** ![ekkehard.horner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/c2a13f/32.png) [@ekkehard.horner](https://www.ruby-forum.com/u/ekkehard.horner)\
**Post date:** [March 25, 2007, 2:47pm UTC](https://www.ruby-forum.com/t/pointer-to-function/90042/2 "2007-03-25T14:47:11Z")

</div>

I have no idea what all that’s supposed to do.  
In Ruby you have methods (and Procs), but focusing on the  
methods–they are invoked by a message. Normally this is done  
magically for you. my\_obj.my\_method sends “my\_method” to “my\_obj”.

Play with it in IRB:

class Me  
def name  
“Paul”  
end  
end  
m = Me.new  
m.name # =\> “Paul”  
m.send :name # =\> “Paul”

class LetSomeRun  
def initialize  
@runnable = %w/first second/  
end  
def first; puts “running first” end  
def second; puts “running second” end  
def run (m)  
if @runnable.include? m  
send m  
else  
raise “Can’t run that!”  
end  
end  
end

r = LetSomeRun.new  
r.run “first”  
r.run “oops” # oops ☹

You could also take a slightly different approach using Proc objects;  
lambda works similar to how `sub {}` works in Perl.  
x = lambda {|name| puts “hello #{name}!”}  
x.call “fred”

So…

class Runnable2  
def initialize  
@runnable = {  
“first” =\> lambda {|this, \*args| this.run “second”, “hello!”},  
“second” =\> lambda {|this, \*args| puts args.first}  
}  
end  
def run (m, \*args)  
@runnable.include? m and @runnable[m].call self, \*args  
end  
end  
Runnable2.new.run “first”

I’m not exactly sure if this answers your question but, enjoy.

Paul

---

<div class="post-metadata">

**Author:** ![ekkehard.horner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/c2a13f/32.png) [@ekkehard.horner](https://www.ruby-forum.com/u/ekkehard.horner)\
**Post date:** [March 25, 2007, 2:49pm UTC](https://www.ruby-forum.com/t/pointer-to-function/90042/3 "2007-03-25T14:49:11Z")

</div>

On Sun, Mar 25, 2007 at 09:10:12PM +0900, ekkehard.horner wrote:

> ```
> my %Fncs = ( 'frsFnc' => ['just tell "frsFnc"', \&frsFnc]
> , 'secFnc' => ['just tell "secFnc"', \&secFnc]
> );
> 
> ```

You have several options, depending on how literally you want to  
translate  
this.

# (1) this is a Method object which is bound to the current object. Use

# fncs[‘frsFnc’][1].call(args…)

# to invoke it

fncs = {  
‘frsFnc’ =\> [‘just tell “frsFnc”’, method(:frsFnc)],  
}

# (2) this is a Symbol giving the _name_ of a method. Use

# some\_object.send(:method, args…)

# to invoke it on an arbitary object (which could be ‘self’)

fncs = {  
‘frsFnc’ =\> [‘just tell “frsFnc”’, :frsFnc],  
}

# (Note: this means you may not need to build the fncs hash at all; just

let

# the caller pass in a method name. This assumes you don’t mind the

caller

# being able to call _any_ method on your object)

# (3) this is an anonymous function, like “sub { … }” in Perl. Use

# fncs[‘frsFnc’][1].call(args…)

# to invoke it.

fncs = {  
‘frsFnc’ =\> [‘just tell “frsFnc”’, proc { puts “hello” }],  
}

A fourth option is to put the callable methods in a Module. Use  
Modname.instance\_method(:method\_name) to get an ‘unbound method’ object,  
which is like a method but not bound to a specific object instance. You  
then  
have to bind it to a particular object when you call it.

There are probably others 🙂

HTH,

Brian.

---

<div class="post-metadata">

**Author:** ![ekkehard.horner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/c2a13f/32.png) [@ekkehard.horner](https://www.ruby-forum.com/u/ekkehard.horner)\
**Post date:** [March 25, 2007, 6:40pm UTC](https://www.ruby-forum.com/t/pointer-to-function/90042/4 "2007-03-25T18:40:44Z")

</div>

With the great help from Paul and Brian I changed just one line of the  
run method  
of my CAPP class:

def run( sFnc )  
puts @name + ‘::run( "’ + sFnc + ‘" )’  
if @Fncs.has\_key?( sFnc )

# use send to call method whose name is contained in sFnc

# todo\_stack.push( “relation between string variable and symbol” )

```
    send sFnc
 else
    puts 'no ' + sFnc + ' in: ' + @Fncs.keys.join( ' ' )
 end

```

end

and got a script that allows me to call CAPP methods by name specified  
on the  
command line, even though I cheated a little bit by using the name ==  
key of  
@Fncs hash instead of the second element of the contained array.

To make myself familiar with the solutions to the ‘pointer to function’  
problem  
provided by Paul and Brian, I added CAPP methods like:

```
 # just to have something to call
   def tell_it( sParm )
     puts @name + '::tell_it( "' + sParm + '" ) called 

```

successfully.’  
end

and - more important:

```
 # obj.send( aSymbol [, args]* ) -> anObject
 # Invokes the method identified by aSymbol, passing it any 

```

arguments specified.  
# You can use **send** if the name send clashes with an existing  
method in obj.  
# Paul: def run (m) … send m … r.run “first”  
# Brian: some\_object.send(:method, args…)  
# fncs = { ‘frsFnc’ =\> [‘just tell “frsFnc”’, :frsFnc], }

```
   def sendSym
     methods = { 'sym0' => ['using :tell_it' , :tell_it] ,
                 'str0' => ['using "tell_it"', "tell_it"] ,
               }
     methods.each { |keyval| send keyval[1][1], keyval[1][0] 

```

}  
end  
# Does send ‘symbolize’ the string? todo: check  
# [The Ruby\_Newbie Guide to Symbols](http://www.troubleshooters.com/codecorn/ruby/symbols.htm)

or:

```
 # obj.method( aSymbol ) -> aMethod
 # Looks up the named method as a receiver in obj, returning a 

```

Method object (or  
# raising NameError). The Method object acts as a closure in obj’s  
object instance,  
# so instance variables and the value of self remain available

```
   def useCall
     methods = { '0' => [ 'using method( :tell_it )', method( 

```

:tell\_it ) ]  
}  
methods.each { |keyval| keyval[1][1].call keyval[1][0]  
}  
end  
# I believe, that’s the way to go

Now I can start to

(a) put an enhanced version of the CAPP class into a module

(b) write a script that will create a new Ruby file \<fname.rb\>  
(requiring/using  
this class CAPP to come) in the current directory, if called like  
ruby xplore.rb new  
resp. will add a new skeleton for method and a suitable  
entry in  
the @methods hash, if called like  
ruby xplore.rb add ‘short description of  
’

(c) explore basic data types, looping, database work, … with Ruby

Thank you very much Paul and Brian. Your answers were exactly what I was  
looking for - and yes I did enjoy this.

Ekkehard

---

<div class="post-metadata">

**Author:** ![ekkehard.horner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/c2a13f/32.png) [@ekkehard.horner](https://www.ruby-forum.com/u/ekkehard.horner)\
**Post date:** [March 25, 2007, 8:12pm UTC](https://www.ruby-forum.com/t/pointer-to-function/90042/5 "2007-03-25T20:12:57Z")

</div>

On Mon, Mar 26, 2007 at 01:40:05AM +0900, ekkehard.horner wrote:

> ```
> def sendSym
> methods = { 'sym0' => ['using :tell_it' , :tell_it] ,
> 'str0' => ['using "tell_it"', "tell_it"] ,
> }
> methods.each { |keyval| send keyval[1][1], keyval[1][0] }
> end
> # Does send 'symbolize' the string? todo: check
> # http://www.troubleshooters.com/codecorn/ruby/symbols.htm
> 
> ```

Yes, send allows you to pass either a string or a symbol. The symbol is  
actually used for method dispatch; if you pass a string then it will  
convert  
it into a symbol first (you can do this explicitly using String#to\_sym  
or  
String#intern; I think they are just aliases)

Regards,

Brian.

---

<div class="post-metadata">

**Author:** ![ekkehard.horner](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/c2a13f/32.png) [@ekkehard.horner](https://www.ruby-forum.com/u/ekkehard.horner)\
**Post date:** [March 25, 2007, 9:26pm UTC](https://www.ruby-forum.com/t/pointer-to-function/90042/6 "2007-03-25T21:26:06Z")

</div>

Brian C. schrieb:

> On Mon, Mar 26, 2007 at 01:40:05AM +0900, ekkehard.horner wrote:  
> […]
> 
> > ```
> > # Does send 'symbolize' the string? todo: check
> > 
> > ```

[…]

> Yes, send allows you to pass either a string or a symbol. The symbol is  
> actually used for method dispatch; if you pass a string then it will convert  
> it into a symbol first (you can do this explicitly using String#to\_sym or  
> String#intern; I think they are just aliases)
> 
> Regards,
> 
> Brian.

Thanks Brian,

I added

def sendStr  
methods = { ‘str0’ =\> [‘using “tell\_it”’, “tell\_it”] ,  
}  
methods.each { |keyval|  
send keyval[1][1].intern, keyval[1][0]  
send keyval[1][1].to\_sym, keyval[1][0]  
}  
end

and learned: When in doubt, use ri (String#to\_sym wasn’t mentioned  
in “ProgrammingRuby.chm”).

Regards

Ekkehard
