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

Ok, if this has already been asked, point me to where the question/answer is, otherwise, here we go:
In CGI.pm, the start_html () method has attributes (attributes, right?), like so:

$q->start_html( -title=>'test');

How does one code a method so you can use such attributes (-title=>, etc.)? Also, I recently posted a node on an 'weird object happening', and I was wondering how one writes a method as opposed to a function?
Any and all help is appreciated.
-Dhoss

And if you're feeling lucky... come and take me home And if you feel loved If you feel lucky, if you feel loved If you feel lucky, if you feel loved You've crossed the walls - Excelled Further along through their hell All for my heart, I watch you kill You always have, you always will Now spread your wings and sail out to me....

Replies are listed 'Best First'.
Re: Methods and attributes?
by Abigail-II (Bishop) on Dec 11, 2003 at 00:32 UTC
    One writes methods in the same way as 'functions' (or subroutines). In fact, while you write them, there is no difference between a method and a 'normal' sub. It's only at *run*time when there's a small difference.

    As for what you call 'attributes', they are just parameters. All parameters are passed to a subroutine (and hence, also a method), as a list. So, in your example, when start_html is call, it's called with three arguments, the first argument is the object on which the method is called, the second argument is the string -title, the third is the string test. It's up to the sub to take the list and turn it into a set of key/value pairs. One common technique is to do: my %args = @_; or some variation. I sometimes write: local %_ = @_;. If a sub is to be called as a method, the first argument of @_ is usually first shifted off.

    Abigail

Re: Methods and attributes?
by Roger (Parson) on Dec 11, 2003 at 00:12 UTC
    Perhaps you should have a look at how CGI.pm does it, ie., read the source code, learn from the master...

    A particularly interesting function is rearrange in CGI::Util that CGI uses to decode the parameters.
    # Smart rearrangement of parameters to allow named parameter # calling. We do the rearangement if: # the first parameter begins with a - sub rearrange { ....
      Ah yes, see, that is where I started. I've looked through somewhat thoroughly with not much luck, so I bet I was missing one of the "decoding" subs.

      And if you're feeling lucky... come and take me home And if you feel loved If you feel lucky, if you feel loved If you feel lucky, if you feel loved You've crossed the walls - Excelled Further along through their hell All for my heart, I watch you kill You always have, you always will Now spread your wings and sail out to me....
        Why writing your own "decoder"? You could just borrow the decoder from CGI. I quickly wrote the following example to show how to decode the named parameters (nicely).
        use strict; use Data::Dumper; use CGI::Util qw/rearrange/; # when called as a method __PACKAGE__->test( -option1=>'a', -option3=>'c' ); # called as a normal function test( -option1=>'a', -option3=>'c', -option2=>'b' ); # called with unnamed parameters test( 'a', 'b', 'c' ); # our little test method/function sub test { my($self,@p) = self_or_default(@_); my($option1,$option2,$option3,@other) = rearrange([qw/ OPTION1 OPTION2 OPTION3 /],@p); print "\$option1=$option1\n\$option2=$option2\n\$option3=$option3\n\ +n"; } # borrowed from CGI.pm with minor modification ;-) sub self_or_default { my $class = __PACKAGE__; # name of the class, set to main for testin +g return @_ if defined($_[0]) && (!ref($_[0])) && ($_[0] eq $class); my $Q = undef; unless (defined($_[0]) && (ref($_[0]) eq $class || UNIVERSAL::isa($_[0], $class))) { $Q = {}; bless $Q, __PACKAGE__; unshift(@_,$Q); } return wantarray ? @_ : $Q; }
        And the output is just what we expected -
        $option1=a $option2= $option3=c $option1=a $option2=b $option3=c $option1=a $option2=b $option3=c
Re: Methods and attributes?
by ysth (Canon) on Dec 11, 2003 at 01:29 UTC
    One way is to assign @_ to a hash. It gets hard to validate that there weren't misspeled attributes that way, so there are helper modules like Params::Validate.
Re: Methods and attributes?
by hanenkamp (Pilgrim) on Dec 11, 2003 at 02:30 UTC

    Shameless Plug: I've written Getargs::Mixed which does named/positional parameters and some validation all in one. (Hubris is a virtue after all.)

    Internally, it's essentially just:

    sub my_sub { my %params = @_; print "Title: $params{-title}\n"; }