http://www.perlmonks.org?node_id=1057825

nitin.sh1982 has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I have a question related to the following code pasted below.

sub new { my ($class, $options) = @_; if (!ref $options) { shift @_; $options = scalar @_ ? {@_} : {}; } #Some Code bless $self, $class; #Some Code return $self; }

I am confused what the line

 $options = scalar @_ ? {@_} : {};

does in this code. What happens to $options after it is executed?

Replies are listed 'Best First'.
Re: Creating 'new' subroutine.
by jwkrahn (Abbot) on Oct 11, 2013 at 06:30 UTC

    Assign a hash reference to $options and if @_ contains any elements then copy those to the hash.

      Thanks. It makes sense. But, what does the 'scalar' do in that case then?

        In that case it is superfluous as @_ is already in scalar context.

Re: Creating 'new' subroutine.
by Anonymous Monk on Oct 11, 2013 at 07:04 UTC
    Is it just me or isn't that equivalent to:
    $options = { @_ };
      > Is it just me or isn't that equivalent to: $options = { @_ };

      Good point, w/o testing I'd say yes !

      Maybe the intention was to check if @_ has even number of elements?

      update

      Still with testing.

      DB<112> use Data::Dump qw/pp/ DB<113> sub tst { pp (scalar @_ ? {@_} : {}); pp {@_};()} DB<114> tst {} {} DB<115> tst a { a => undef } { a => undef } DB<116> tst a,1 { a => 1 } { a => 1 }

      Cheers Rolf

      ( addicted to the Perl Programming Language)

        If we're guessing at intentions, then I might wager:

        $options = scalar(@_) == 1 ? $_[0] : { @_ };

        Though that's probably better written as:

        $options = { scalar(@_) == 1 ? %{$_[0]} : @_ };

        ... to deliberately shallow clone in the case of a hashref.

        use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name
        Even if the intention was to write it with a check for evenness, @_ % 2 == 0 ? {@_} : {}, it would be very poor coding practise to just silently discard the options supplied by the user (if odd).

        My own quick check confirms what LanX (Rolf) just posted. But with respect for checking for an even number of elements, I wouldn't bother.

        One would probably want the fatal error if an odd number was present sense one would most likely be expecting named args coming in. Letting it die is probably the correct course of action.

        The answer to the question "Can we do this?" is always an emphatic "Yes!" Just give me enough time and money.
      if the second element is empty
      then shift @_ moves to the $_ nothing
      which means scalar @_ returns zero
      in which case : {} adds into hash nothing,
      but creates reference to it
      so $options {@_} would do the trick, I guess

      please correct if it's wrong

      updated


      thanks for the correction snippet was incorrect
        @_ is an array, an array in scalar context returns the number of elements (a number), and anumber is never a reference
        Thanks for the reply. I still am far from testing it as we are running on mac, and are struggling with the setup. So, do you mean scalar @_ determines how many elements to be added into hash while creating the reference?