Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Re^2: RFC: "assignary" operator ?= :

by richard.sharpe (Sexton)
on Dec 07, 2019 at 16:34 UTC ( [id://11109810]=note: print w/replies, xml ) Need Help??


in reply to Re: RFC: "assignary" operator ?= :
in thread RFC: "assignary" operator ?= :

I wouldn't call it a need, just preference. I would like "exploiting" such feature this way:

$var1 ?= die "ERROR: \$var1 already set." : $var2;

Maybe you'll see more elegant way how to do such thing.

Your suggestion with ||= is not ternary, just "binary", if I understand that correctly.

Replies are listed 'Best First'.
Re^3: RFC: "assignary" operator ?= :
by LanX (Saint) on Dec 07, 2019 at 16:49 UTC
    > not ternary, just "binary",

    yes it's binary.

    > $var1 ?= die "ERROR: \$var1 already set." : $var2;

    Thanks for demonstrating your use case, it's even stranger than I expected! ;-)

    die will not return a value - actually it won't return at all.

    > Maybe you'll see more elegant way how to do such thing.

    Yes with a properly named custom-function operating on an alias.

    something like

    sub init { die "ERROR: \$var already set." if defined $_[0]; $_[0] = $_[1]; } init $var1 => 'value1'; # pretty elegant, right? init $var2 => 'value2'; init $var3 => 'value3';

    Please note the defined° , cause else wise you'd miss false values like 0 or "". (which renders your requirement for a new operator a bit useless)

    UPDATE:
    • if you need the proper $var name use PadWalker
    • use Carp to report from the perspective of the caller

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

    °) a shorter way would have been $_[0] // die 'ERROR: ...';

    Off by one, it's the inverted case :)

      Yes with a properly named custom-function operating on an alias.
      init $var1 => 'value1'; # pretty elegant, right?

      No, not at all. First, init() is a poor name which doesn't, by name, tell at all what it is doing. Second, the sub you wrote isn't at all ternary in any way, since it misses $_[2]. Third and last, function LIST doesn't tell at first glance that it is about conditional assignment to $_[0] from either $_[1] or $_[2] based on defined-ness of $_[0].

      perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
        > Second, the sub you wrote isn't at all ternary in any way

        It's an XY problem, the use case wasn't ternary from the beginning.

        But you're welcome to impress us with a better solution.

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

      Thank you, Rolf (and also other guys).

      Personally I'd prefer for such "basic thing" something "exactly explicit" just where it's used, without packaging/hiding it in the subroutine defined elsewhere. I prefer using custom subroutines for bit less simple logic (just personal preference).

      About no return from dying: yes, I really don't need returning from that death, therefore I called that "exploiting". But maybe somebody will find also other use cases for such "assignary" operator, not just this one.

      In the context of my practise (as used in my scripts and modules), I initialize (define) all my local variables just with heir my, to be more explict, what type of value are they predetermined to bear (number, string, hashref, etc.), e. g.:

      my $string = '';

      and therefore I don't need to differentiate undef from '', which means "not set" in my example.

      But, in case, of undefined variable used in assignary, e.g.:

      my $some_undefined_var; $some_undefined_var ?= die 'already set' : 'survived';

      on my opionion, it could stay alive, and "use of uninitialized value" warning raised on use warnings;.

Re^3: RFC: "assignary" operator ?= :
by ikegami (Patriarch) on Dec 07, 2019 at 17:03 UTC
    $var1 ?= die "ERROR: \$var1 already set." : $var2;

    would be far clearer as

    die "ERROR: \$var1 already set." if $var1; $var1 = $var2;

      Personally I feel this just obfuscates the problem at hand, but I dislike/hate statement-modifiers in general.

      $var1 and die "ERROR: ..."; $var1 = $var2;

      To **me** is extremely better readable (and thus maintanable) than your suggestion. TIMTOWTDI.


      Enjoy, Have FUN! H.Merijn

        Personally, I despise people that hide die and other flow control statements. (Put a line break before the and and a blank line after die!)

        Either way. The point is the separation of the two actions.

Re^3: RFC: "assignary" operator ?= :
by tobyink (Canon) on Dec 08, 2019 at 00:55 UTC

    This is a pretty cute alternative:

    sub empty ($) :lvalue { if ($_[0]) { require Carp; if (eval { require PadWalker }) { my $varname = PadWalker::var_name(1, \$_[0]); Carp::croak("$varname is not empty, stopped"); } Carp::croak("Variable is not empty, stopped"); } $_[0]; } # Asserts that $var1 is "empty" (i.e. the empty string, 0, or undef) a +nd assigns $var2 as the new value. empty $var1 = $var2; # Can also be used like this to assert $var1 is empty without assignin +g a new value. empty $var1;
      nice! :)

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (7)
As of 2024-04-19 10:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found