dejoha has asked for the wisdom of the Perl Monks concerning the following question:

I have a new question dealing with OO programming.

Taking some advice from the O'Reilly book, Perl Cookbook, recipe 19.12, I've worked up a CGI program that uses a %hash to pick from a variety of functions.

I'd like to call these as methods, instead of just functions, but I can't figure out how. Likely, this has a simple solution.

Relevent code:

sub prepare { my $class = shift; my $quiz = bless { }, $class; $quiz->init(@_); return $quiz; } sub begin { my $quiz = shift; # What should PopQuiz do? my $switchbox = { 'show' => \&Take_A_Quiz, 'list' => \&Quiz_List, 'score' => \&Score_Quiz, 'submit' => \&Submit_Quiz, }; # Pick Mode my $mode = $quiz->{params}{'__mode'} || 'list'; # Prepare the act to be performed my $act = $switchbox->{$mode}; # Perform &{$act}($quiz); }

Instead of calling &{ $act }( $quiz ), I would like to call the method, $quiz->$act( ); -- or something like this? Normally, I call methods in this fashion:

$quiz->method;

In another subroutine, I am using a similar %hash to call other functions:

my %valid_question = ( 'boolean' => \&parse_boolean, 'multiple' => \&parse_multiple, 'identify' => \&parse_identify, 'essay' => \&parse_essay ); my $parse_type = $valid_question{ lc( $input ) };

Now, I want to call a method, but the only way I've figured out how to do it is this:

&{ $parse_type }( $quiz, @params );

I wish I could do this OO style, and not have to pass the object literally:

$quiz->$parse_type( @params );

I have a working example of the script online:

http://www.camandshayna.com/quiz/popquiz.cgi

Thanks,

~derek

Replies are listed 'Best First'.
Re: Calling OO-method From A Hash
by Anonymous Monk on Mar 03, 2004 at 02:50 UTC
    You said it yourself: $quiz->$act()

      Of course the truly paranoid will make sure that it's a valid method first.

      my $method = $q->param( 'method' ); # ... or whatever if( my $m = $obj->can( $method ) ) { $obj->$m( @params ); } else { die "I can't call $method on a ", ref $obj; }
        beware of method names like "main::unsafe" for example. can() will return \&main::unsafe and not undef. this is also addressed in perlsec.pod.
        better will be checking in a dispatch table in case $method comes from outside.
        A reply falls below the community's threshold of quality. You may see it by logging in.

        And the knowledgable would know that the extra code doesn't get you much, since calling an invalid method will die as it is...

      Thanks!

      This worked perfectly. I don't know what I was smoking! Maybe I just needed to tell someone else.

      Sorry to bother the Monks with such trivialities…

      www.dejoha.com … www.derekandmelissa.com
      I'd like to make a small note, namely despite being a symbolic reference (in my book),
      $quiz->$act()
      passes strict without any form of complaint.
      use strict; sub Foo::hello { shift; printf "Hello, %s!\n", shift; } my $meth = "hello"; my $class = "Foo"; $class->$meth("world");
        Method lookup is done at runtime. So, what's wrong with allowing an extra dereference?

        It does bring up the point that $class->$meth() is not the same as $meth($class). (It is, however, the same as $class->can($meth)->($class). *grins*)

        ------
        We are the carpenters and bricklayers of the Information Age.

        Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

The debugger is your friend
by TomDLux (Vicar) on Mar 03, 2004 at 06:51 UTC

    You reason about what should work in theory.

    The next step should be to give it a try. Write something in the code, then use the debugger to run the code. Since you can type code expressions into the debugger, at the suitable line you can experiment with what seems reasonable to you, and have it be more than just cargo-cult progrramming. By typing in an expression and seeing what is returned, you can gain an understanding of what your data actually contains. WOW! --- Genetic Algorithms applied to running code!

    P.S. I have become adept at typing use Data::Dumper; in the debugger.

    Update: Changed title.

    --
    TTTATCGGTCGTTATATAGATGTTTGCA