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

Is this the cleanest way to do this, or does someone have a suggestion for improvement? I probably have to parenthesize the assignment.
my ($self, $file) = ($_[0], $_[1] ? $_[0]->{file} = $_[1] : $_[0]->{file} ) ;

If a file argument is passed in, then the new value for $self->{file} is this new argument. Otherwise, set file to the value of $self->{file} already bound. We are guaranteed to always have a value here because the object constructor requires it.

Replies are listed 'Best First'.
Re: choosing and/or overriding defaults for a sub argument
by danger (Priest) on May 22, 2001 at 01:13 UTC

    Some of the responses thus far won't properly handle a filename that evaluates to false (filename is '0' perhaps). Since you are using $self may I assume you are writing an object method? If so, perhaps you want to provide a get/set method to the file attribute and just call that appropriately within your other method:

    sub whatever { my $self = shift; my $file = $self->file(@_); # ... do stuff } sub file { my $self = shift; $self->{file} = shift if @_; $self->{file}; }
Re: choosing and/or overriding defaults for a sub argument
by Masem (Monsignor) on May 22, 2001 at 00:42 UTC
    How about (thank you || operator!)
    my ( $self, $file ) = ( $_[0], ( $_[0]->{file} = $_[1] || $_[0]->{file} ) );
    Though if you are setting ->{file}, do you really need $file?
    my $self = shift; $self->{file} = shift || $self->{file}; # or... $file = $self->{file} = shift || $self->{file};

    Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain
      even better (i think):
      my $self = shift; $self->{file} = shift if @_; my $file = $self->{file}; # or just leave this out and use $self->{fil +e}
Re: choosing and/or overriding defaults for a sub argument
by ton (Friar) on May 22, 2001 at 00:42 UTC
    The logic looks good to me, but I prefer this slightly more readable implementation:
    my $self = shift; my $file = $self->{'file'} = shift || $self->{'file'};
    -Ton
    -----
    Be bloody, bold, and resolute; laugh to scorn
    The power of man...
Re: choosing and/or overriding defaults for a sub argument
by arturo (Vicar) on May 22, 2001 at 00:43 UTC

    That way works for me but I find this way of writing it to be more easily grokkable:

    sub file { my $self = shift; @_ ? $self->{file} = shift : $self->{file}; }

    update hmm, sorry, that doesn't do exactly what you want I suppose. But you could always substitute $self->{file} or even $self->file() in place of $file through the rest of the method ... but, as my physics instructor never said, "whatever applies sufficient surface tension underneath your watercraft to maintain it above the liguid-gas boundary."

    perl -e 'print "How sweet does a rose smell? "; chomp ($n = <STDIN>); +$rose = "smells sweet to degree $n"; *other_name = *rose; print "$oth +er_name\n"'
Re: choosing and/or overriding defaults for a sub argument
by srawls (Friar) on May 22, 2001 at 00:43 UTC
    Your code is fine, but you can try this if you want:
    my ($self, $file) = ($_[0],$_[0]->{file}||=$_[1]);


    The 15 year old, freshman programmer,
    Stephen Rawls

      Unfortunately, that only sets $file to the second argument passed if $self->{file} isn't already set (to a true value, but I assume any filename passed will evaluate to true), which doesn't seem to be what princepawn wants (which is to set $file to be the second value passed if passed, or to be the value of $self->{file} otherwise).

Re: choosing and/or overriding defaults for a sub argument
by Brovnik (Hermit) on May 22, 2001 at 00:59 UTC
    Is the $file being passed in a filename or a reference ? If it is just a filename, then "set file to the value of $self->{file} already bound." won't work since the value doesn't get back to the caller.

    Maybe what you want is for the call in the program to obj->file("Filename"); to store the filename internally, and my $fn = obj->file(); to return it.

    If so, your code needs to look more like :

    sub filename { my ($self, $file) = @_; $self->{file} = $file if $file; return $self->{file}; }
    to get the file back to the caller.

    I don't like the $self->{'file'} = shift || $self->{'file'}; idea, since setting something to itself when you don't need to is less clear.
    --
    Brovnik

Re: choosing and/or overriding defaults for a sub argument
by princepawn (Parson) on May 22, 2001 at 00:45 UTC
    I have to transform a lot of code, and it will be easy to simply change the @_ to something like the above instead of changing the inline usage of $file all over the place.