Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Passing a list to an Object

by lzcd (Pilgrim)
on Jan 13, 2001 at 06:37 UTC ( [id://51543]=perlquestion: print w/replies, xml ) Need Help??

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

Howdy,

What would a journey towards monk'dom be without a newbie question?

In my ongoing descovery of perl, I finally decided to tackle the whole OO side of the pie... in very small chunks.

Say for instance I've got a happy little piece of code such as:
{ package MyObject: sub doThat { my (%ARGS) = ( chew => 'meat', @_); return 'I like '.$ARGS{chew).'!'."\n"; } }

Now I was expecting to be able to go MyObject->doThat(chew=>'bananas') and recieve 'I like bananas!'.
But instead I get 'I like meat!'.

Normally the @_ should overwrite the default value, right?

What's so different with package/object dodads?

Oh where have I strayed from the enlightened path?

Replies are listed 'Best First'.
Re: Passing a list to an Object
by danger (Priest) on Jan 13, 2001 at 06:54 UTC

    First of all, there were a couple syntax errors in your posted code, please paste in the real code whenever possible to avoid typos.

    When making an object or class method call like:

    $obj->method(arg); #or Class->method(arg); # your example

    The method actually receives the $obj or 'Class name' as its first argument (depending on which call you made). So in your example, in your doThat() method you are assigning the following:  %ARGS = ('chew', 'meat', 'MyObject', 'chew', 'bananas').

    So, 'MyObjects' is taken as a key with a value of 'chew' and 'bananas' is left just sitting there doing nothing. If you had -w turned on you would have been warned about assigning an odd number of elements to a hash.

      Sorry about the typo's.

      Okay now that I've got this situation, what's the easiest way to get around it?

      How does one pass a list and not wind up with an odd numbered hash?

        Simply shift off the first argument from @_ before proceeding with messing with it:

        sub doThat { my $self = shift; my %ARGS = (chew => 'meat', @_); return "I like to chew $ARGS{chew}!\n"; }
Re: Passing a list to an Object
by repson (Chaplain) on Jan 13, 2001 at 11:11 UTC
    I know danger has already answered your question, but I thought I'd show another possibly clearer way to accomplish your aim, using a slightly different style.
    sub do_that { my $self = shift; my %args = ref($_[0]) ? %{$_[0]} : @_; $args{chew} ||= $self->{food} || 'meat'; return "I like $args{chew)!\n"; }
      Thank you for your second opinion. :)

      I seem to remember that hash arrays aren't known for thier default sorting abilities (eg. they may not keep their original insertion order.).
      Doesn't a shift run the risk of killing an unintended list item?
      (...or am I just getting lists, hashes and small terriers named 'Spanky' all turned around at this wrong hour of the day?)
        When you say
        MyClass->doThat(chew=>'bananas')
        The arguments don't get passed as a hash. '=>' doesn't automatically transform things into hashes, but instead is the equivalent of a comma, with the side effect of ensuring that the word before it is interpreted as a string. So it's the equivalent of saying:
        MyClass->doThat('chew', 'bananas')
        Or even:
        MyClass::doThat('MyClass', 'chew', 'bananas')
        So it's a list, not a hash, and you don't need to worry about order getting scrambled. The list doesn't turn into a hash until you do something like:
        sub doThat { my $type = shift; my %input = @_; }
        Then, you've copied the list into an associative array. Until then, plain-vanilla list... Sorry to flog a dead horse, but I saw a misconception waiting to happen...

        stephen

        No, as danger says above, if a funtion/method is called as Class->method(); or $instance->method();, the first argument will always be the part before the class name or instance variable. He didn't mention the indirect syntax ie method Class ();, which acts the same way as the direct syntax, but is less clear except for $foo = new Class;.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://51543]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (3)
As of 2024-04-26 00:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found