[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

pointer to function

ekkehard.horner

3/25/2007 12:06:00 PM

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
13 Answers

Paul Stickney

3/25/2007 12:46:00 PM

0

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

Brian Candler

3/25/2007 12:48:00 PM

0

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.

ekkehard.horner

3/25/2007 4:39:00 PM

0

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
# http://www.troubleshooters.com/codecorn/ruby/s...

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 <fname> new
resp. will add a new skeleton for method <mname> and a suitable entry in
the @methods hash, if called like
ruby xplore.rb <fname> add <mname> 'short description of <mname>'

(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

Brian Candler

3/25/2007 6:12:00 PM

0

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/s...

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.

ekkehard.horner

3/25/2007 7:24:00 PM

0

Brian Candler 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

SlackJaw

8/13/2007 12:42:00 AM

0

Red wrote:

> On Aug 10, 4:52?pm, Red with his KKK sheet over his head
> <redtheklukluxklan...@aol.com> wrote:
> > In article <1186710241.240562.245...@i38g2000prf.googlegroups.com>,
> >
> >
> >
> >
> >
> > Red <RedRedCoun...@aol.com> wrote:
> > > On Aug 9, 7:45?pm, fargo116 <fargo...@yahoo.com> wrote:
> > > > On Aug 9, 4:43 pm, Red <redredcount...@aol.com> wrote:
> >
> > > > > On Aug 9, 6:28?pm, "Black Elk" <windriver2...@yahoo.com>
> > > > > wrote:
> >
> > > > > > "Red" <redredcount...@aol.com> wrote in message
> >
> > > > > > Clinton had Rawanda; Bush has Afghanistan, Iraq, Darfur,
> > > > > > Iran, the U.S. and
> > > > > > on and on....
> >
> > > > > More death in Rwanda than all those other countries put
> > > > > together.
> >
> > > > LOL. 'But look at what Clinton did!"
> >
> > > > Aw. c'mon Red. Stop your fake sympathy before it makes me cry
> > > > my eyes out. Those folks in Darfur are dirt poor and we know
> > > > what you think of the poor.
> >
> > > > S. Olson
> >
> > > Since when did you take up mind reading? I think you're
> > > projecting, are you not!
> >
> > It is common knowledge you sit at your computer with your klu klux
> > klan sheet over your head typing away at you computer, waiting for
> > that email that you can go with your friends to burn a cross in
> > some fag or niggers lawn.

Hmm, you may be confued. That sounds like Democrat Robert E. Byrd, of
the KKK.

- Hide quoted text -
> >
> > - Show quoted text -
>
> I can hardly see without glasses. If I was wearing a hood I don't
> think I could see anything. It's warm & wonderful that you like me,
> thanks.

SlackJaw

8/13/2007 11:40:00 PM

0

fargo116 wrote:

> On Aug 12, 6:42 pm, "SlackJaw" <Slack...@Hotmail.com> wrote:
> > Red wrote:
> > > On Aug 10, 4:52?pm, Red with his KKK sheet over his head
> > > <redtheklukluxklan...@aol.com> wrote:
> > > > In article
> > > > <1186710241.240562.245...@i38g2000prf.googlegroups.com>,
> >
> > > > Red <RedRedCoun...@aol.com> wrote:
> > > > > On Aug 9, 7:45?pm, fargo116 <fargo...@yahoo.com> wrote:
> > > > > > On Aug 9, 4:43 pm, Red <redredcount...@aol.com> wrote:
> >
> > > > > > > On Aug 9, 6:28?pm, "Black Elk" <windriver2...@yahoo.com>
> > > > > > > wrote:
> >
> > > > > > > > "Red" <redredcount...@aol.com> wrote in message
> >
> > > > > > > > Clinton had Rawanda; Bush has Afghanistan, Iraq, Darfur,
> > > > > > > > Iran, the U.S. and
> > > > > > > > on and on....
> >
> > > > > > > More death in Rwanda than all those other countries put
> > > > > > > together.
> >
> > > > > > LOL. 'But look at what Clinton did!"
> >
> > > > > > Aw. c'mon Red. Stop your fake sympathy before it makes me
> > > > > > cry my eyes out. Those folks in Darfur are dirt poor and we
> > > > > > know what you think of the poor.
> >
> > > > > > S. Olson
> >
> > > > > Since when did you take up mind reading? I think you're
> > > > > projecting, are you not!
> >
> > > > It is common knowledge you sit at your computer with your klu
> > > > klux klan sheet over your head typing away at you computer,
> > > > waiting for that email that you can go with your friends to
> > > > burn a cross in some fag or niggers lawn.
> >
> > Hmm, you may be confued. That sounds like Democrat Robert E. Byrd,
> > of the KKK.
>
> The difference is that Sen. Byrd left the KKK long ago,

So he says, but why does he keep contact with his KKK buddies?

Of course, the difference between the GOP and Dems is that the GOP does
NOT elect former KKK members to congress.

>unlike Pimple,



> who's sopping kerosene on a cross with a mop for the next meeting.
>
> S. Olson

SlackJaw

8/13/2007 11:41:00 PM

0

Red wrote:

>
> You types just hate the truth. That's all. When someone makes it
> their aim to attack anything you post it's because they've become
> obsessed with you. I accept that challenge and will continue to post
> more real stories. You can refute me but never the stories. Bark
> doggy, sit doggy, now you're my bitch.

Remember, they don't hate you coz you're wrong - they hate you because
they're afraid that you're right.

SlackJaw

8/14/2007 1:49:00 AM

0

fargo116 wrote:

> > Of course, the difference between the GOP and Dems is that the GOP
> > does NOT elect former KKK members to congress.
>
> It just misquotes them on the House floor, like Rep. Poe of Texas did
> three months ago. Byrd hasn't been involved with the KKK for 60 years.

Are the niggers he lynched still dead?


The GOP won't allow any former KKK member in - while the Democrats
welcomed him even while he was still a member

> LOL
>
> S. Olson

SlackJaw

8/15/2007 12:29:00 AM

0

fargo116 wrote:

> On Aug 13, 7:49 pm, "SlackJaw" <Slack...@Hotmail.com> wrote:
> > fargo116 wrote:
> > > > Of course, the difference between the GOP and Dems is that the
> > > > GOP does NOT elect former KKK members to congress.
> >
> > > It just misquotes them on the House floor, like Rep. Poe of Texas
> > > did three months ago. Byrd hasn't been involved with the KKK for
> > > 60 years.
> >
> > Are the niggers he lynched still dead?
>
>
> LMAO!. Hey Slack, name three.

Three? Ho wmany were there?

> I know of no instances where Byrd
> lynched anyone or took part in a lynching.

No offense, but there may be a lot of things you don't know.

> But maybe you can tell us
> who the folks he supposedly lynched were?
>

Did he ever come clean and list his KKK activites?


> I like how you refer to Black people as 'niggers,' too. Boy, THAT sure
> doesn't show any racial prejudice.

That's the word KKK members like Byrd use.


>
> > The GOP won't allow any former KKK member in - while the Democrats
> > welcomed him even while he was still a member
>
> That would be in 1942, right?


>Yet, Rep. Poe of Texas misquoted the
> founder of the KKK just three months ago while talking about our
> soldiers. I believe you'll find he's a Republican.
>
> S. Olson

Rather I should die a thousand times, and see Old Glory trampled in the
dirt never to rise again, than to see this beloved land of ours become
degraded by race mongrels, a throwback to the blackest specimen from
the wilds. _ Robert Byrd