CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Advanced:
to ref or not to ref

 



perlplexer
Deleted

Dec 1, 2000, 7:35 AM

Post #1 of 2 (683 views)
to ref or not to ref Can't Post

Hey people!

I am trying to write a code fragment that will create a menu using Tk. The code should
take two arguments: @buttons and %actions,
where @buttons contains all the names and %
actions contains references to subs that must
be executed when user hits a button.
([()],[()],[()] may be more efficient but
that's not the point here)

Here is my first try on this:
----------------Code A---------------------
my @buttons = ("Display Log Files",);
my %actions = ();
@actions{@buttons} = (\&DisplayLog);
$top = MainWindow->new();
foreach $button (@buttons){
$top->Button(-text => $button, -command => sub{$actions{$button}($top)})->pack;
}
MainLoop;
exit;
---------------------------------------------
The code compiles but does not work as expected because $button becomes "" after
the 'foreach' loop and everytime user hits a button I get "Undefined subroutine &main:: called at line blah..."

Now, if you still follow, look at the following fragment:

-------------------Code B--------------------
my @buttons = ("Display Log Files",);
my %actions = ();
@actions{@buttons} = ('DisplayLog');
$top = MainWindow->new();
foreach $button (@buttons){
$code = '$top->Button(-text => $button, -command => sub{'."$actions{$button}".q/($top)}); return 1;/;
print "Eval failed\n" unless eval $code;
}
MainLoop;
exit;
-------------------------------------------

This code compiles and runs fine.
BUT! I don't like it because it uses eval().

The question is, is there a way to do the same thing without using eval? I would really prefer to use references...


perlplexer
Deleted

Dec 1, 2000, 9:42 AM

Post #2 of 2 (683 views)
Re: to ref or not to ref [In reply to] Can't Post

Never mind... :)

Turned out to be pretty easy...

------------Code I like---------------------
my @buttons = ("Display Log Files");
my $flag = @buttons;
my %actions = ();
@actions{@buttons} = (\&DisplayLog);
$top = MainWindow->new();
foreach $button (@buttons){
my $cref = sub{ my $item = shift; return sub{ $actions{$item}($top) } }->($button);
$top->Button(-text => $button, -command => ${[$cref]}[0])->pack;
}
MainLoop;
exit;
--------------------------------------------

perlplexer

PS: closures rule! :)))

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives