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

The question is simple, but fun. :-)
What can I say, I'm a curious sort.

Assuming your module has a ->new() and ->printme() method, and you want to pass options into it, what is your favorite method of doing so and why? I would still say that these are options that are getting passed after the core parameters for a method are passed.

Is this strictly a form over function issue, or are there and good reasons to prefer one over the other?

edited: Mon Aug 19 23:26:50 2002 by jeffa - closed ul tag

Replies are listed 'Best First'.
Re: What's your favorite method of passing parameters into a sub?
by sauoq (Abbot) on Aug 19, 2002 at 20:42 UTC

    If you want named parameters, I'd suggest using the first method. If you want to operate on data stored in a hash, pass a hash ref. I don't like the idea of using a hash reference to pass in named parameters because the calls will mostly have those ugly additional braces.

    I think a better question might be, "when should I use named parameters?"

    My thoughts on that are that they should only be used where the parameters in question set features of a fairly complex datatype. Some examples:

    my $shape = Box->new(length=>10, width=>5, height=>3); # might make s +ense. my $string = SuperString->new(text=>"foobar"); # probably doe +sn't. my $substr = mysubstr(Search=>"bigbigstring",For=>"big", Occurence=>2) +; # UGLY!

    I've actually seen interns, apparently far too impressed with CGI.pm, write code like the third example. Please don't.

    -sauoq
    "My two cents aren't worth a dime.";
    
Re: What's your favorite method of passing parameters into a sub?
by blokhead (Monsignor) on Aug 19, 2002 at 21:27 UTC
    I recently rolled my own Class::DBI-ish module, which creates objects from DB tables. It provides a search() method to its subclasses to find these objects. I've found the most intuitive way to write calls to this method is using named parameters:
    my @people = People->search( position=>'manager', last_name=>'Smith' ) +;
    as opposed to
    my @people = People->search('position', 'manager', 'last_name', 'Smith +'); # or my @people = People->search({ position=>'manager', last_name=>'Smith' +});

    I like the first way for a few reasons: first, when using a hash as opposed to an array, the relationship between the pairs of parameters is very clear. Clearly position and 'manager' are related items in this method call. This is less clear in the array version. Also, I like being able to have barewords with the hash version -- less quotes I have to type. And no curly braces like in the hashref 3rd version.

    This method makes more logical sense to me, and is easiest to type. However, I would probably use a hashref if the named parameters were combined with unnamed parameters, such as:

    $x->text('hello world', { font=>'arial', size=>'12px' });

    ... just so I could visually separate the "important" data from the less-important formatting arguments.

    All in all, it's probably more important to stive for consistency than which specific style you choose. Having said that, most of the methods I encounter are not good candidates for named parameters, as in the above substr() example by sauoq

Re: What's your favorite method of passing parameters into a sub?
by Abigail-II (Bishop) on Aug 20, 2002 at 12:58 UTC
    I use named parameters all the time - it gives you the most flexible interface, and you don't need to look up the order of the parameters. It also makes the calls themself clearer.

    But I never use the hashref method to pass in parameters. It's ugly, pointless and just adds punctuation without any gain.

    I also like to use local %_ = @_ to put the named parameters in a hash.

    Abigail

      It's ugly, pointless and just adds punctuation without any gain.

      I think I mostly agree with that statement. However, I would also tend to think that passing in 1 hashref vs. 2*n parameters would be more efficient in some situations...mainly if the hashref of opts you pass in will also get forwarded into an internal serializer class method(s) or some such foo.

      Now granted, you could just pass \%args, and the performance difference is probably not measureable so it's all a matter of taste again I guess.

      I agree, it's ugly and pointless on a ->new( {option1=>'on'} ) call, where there is no strict set of parameters, just 'options', but on a class method, I would think it more desireable ->dostuff('param1', {option1=>'on', option2=>'0'}).

      -=Chris

        I think I mostly agree with that statement. However, I would also tend to think that passing in 1 hashref vs. 2*n parameters would be more efficient in some situations...mainly if the hashref of opts you pass in will also get forwarded into an internal serializer class method(s) or some such foo.
        You mean, compared to the overhead of actually calling a sub? You'll have to create a far fetched example to make a significant difference. And there's of course always &func;.
        I agree, it's ugly and pointless on a ->new( {option1=>'on'} ) call, where there is no strict set of parameters, just 'options', but on a class method, I would think it more desireable ->dostuff('param1', {option1=>'on', option2=>'0'}).
        This confuses me. The first one suggests it's a constructor, and constructors often are class methods as well. So why is a hashref ugly in the first example, but more desireble in the second? (For me, they all subs - whether they are used as methods (either class or object) or not).

        Abigail

Re: What's your favorite method of passing parameters into a sub?
by jk2addict (Chaplain) on Aug 20, 2002 at 00:35 UTC

    edited: Mon Aug 19 23:26:50 2002 by jeffa - closed ul tag

    Damn disgraceful. I be a webb devloper n stufs.
    Sorry about that.

    -=Chris

Re: What's your favorite method of passing parameters into a sub?
by vek (Prior) on Aug 19, 2002 at 20:20 UTC
    I posted a similar question a while back. That thread should prove helpful.

    Update: Apon re-reading the question I see that the node I referenced has little to do with the question at hand - please disregard.

    -- vek --