Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

What operator should perl5porters use for safe dereferencing?

by de-merphq (Beadle)
on May 29, 2012 at 13:24 UTC ( #973015=poll: print w/ replies, xml ) Need Help??

vote on What operator should perl5porters use for safe dereferencing?

There is an open discussion on perl5porters about adding a new "safe de-reference" operator. This operator would basically cause things like my $foo= $bar-XX>method(); to be "safe" should $bar be undefined, and cause $foo to be equal to "undef". Which operator do you think is appropriate? (Yes for once the poll is serious :-)
~>
[bar] 305/30%
&>
[bar] 27/3%
?>
[bar] 53/5%
+>
[bar] 23/2%
!>
[bar] 36/4%
->>
[bar] 81/8%
->->
[bar] 25/2%
==>
[bar] 63/6%
?->
[bar] 122/12%
->?
[bar] 51/5%
&->
[bar] 20/2%
&&->
[bar] 16/2%
-&>
[bar] 13/1%
-&&>
[bar] 15/1%
->&
[bar] 21/2%
->&&
[bar] 12/1%
-=>
[bar] 23/2%
=->
[bar] 17/2%
None
[bar] 103/10%
1026 total votes
Comment on What operator should perl5porters use for safe dereferencing?
Re: What operator should perl5porters use for safe dereferencing?
by Corion (Pope) on May 29, 2012 at 13:26 UTC
      Indeed. The whole point of posting this poll is to provide a place to canvas the communities preferences without swamping the list with bike-shedding. :-)
      ---
      alter ego of demerphq
Re: What operator should perl5porters use for safe dereferencing?
by Anonymous Monk on May 29, 2012 at 13:43 UTC

    Meh!

    I would have really liked a NO poll option

    I voted  ->> but  ~> also looks about the same, plus its one char shorter

    Even if this does get introduced, I'll be using  my $foo = eval { ro->sham->bo->die };

    dor is actuall usefuly ( //= ) but this, not so much, eval{} works

      Ill add a "none" option. Anyway, stick with eval if you want, me personally I think using eval for this purpose is pretty close to using a nuke to swat a fly, and about as efficient.
      ---
      alter ego of demerphq

        Anyway, stick with eval if you want, me personally I think using eval for this purpose is pretty close to using a nuke to swat a fly, and about as efficient.

        lol, are you wearing EPIC colored glasses or something?

        How about a "No clue - I don't even know what this is about" for the dummies among us? ;-)

      eval{} surely works. But it works too well. Far too well! It'll happily eat any exception whatsoever. Sure you will be able to tell whether it's the kind of exception that happens when calling a method on an undef, but will it be one of the calls you have here or is it somewhere deep down within one of the methods?

      <!-- Node text goes above. Div tags should contain sig only - ->

      Jenda
      Enoch was right!
      Enjoy the last years of Rome.

        eval{} surely works. But it works too well. Far too well! It'll happily eat any exception whatsoever. Sure you will be able to tell whether it's the kind of exception that happens when calling a method on an undef, but will it be one of the calls you have here or is it somewhere deep down within one of the methods?

        For me, I don't see that as a problem, either I want exceptions, or I want to ignore them

        I doubt there exists a situation where I would want to ignore only this particular exception:

        Can't call method "%" on an undefined value

        But if there was, I'm sure I'd use one of cpan's exception filtering modules instead of  ~>

      eval is not equivalent. Not even close. While it does the job, it does significant collateral damage in the process, so it doesn't work at all as far as I'm concerned.

      I'm not saying we need this feature. I'm simply saying "just use eval" is wrong.

        eval is not equivalent. Not even close. While it does the job, it does significant collateral damage in the process, so it doesn't work at all as far as I'm concerned.

        wow, you're rally onto something

      ~> is less characters, but is more travel. I like ->> because it's the same input as -> but with the last character repeated.

      ~> also looks too similar to -> on some fonts at a glance, so ->> has the advantage of being shaped differently. Of course it does have the disadvantage that a junior might think it's a typo and 'fix' it.

        I agree,
        ~> and
        -> are just too similar.

        Depending on the font (and you can not always choose the one you like, especially online), you really have to look hard. I pretty much guarantee that code audits as well as helping out on SoPW will get a lot harder.

        As for the typing effort, a character more or less really doesn't matter. Those of us who use non-english keyboards (so, most of us really) already have a hard time coding Perl and other programming languages. Some examples from my german keyboard:

        • ~ is (Alt Gr)(+)
        • \ is (Alt Gr)()
        • { is (Alt Gr)(7)
        • [ is (Alt Gr)(8)

        In effect, a lot of the "standard" metacharacters require awkward right-hand-only acrobatics. I thought about using an english/american keyboard, but since i also require german umlauts that would just shift the problem. Just changing the keyboard layout in software is also a bit awkward, since then the printing on the keys does not match what i type (which i find rather confusing).

        In short, i don't care if i have to type two or three characters, since something like ?-> is easier to read and harder to overlook (and in this case actually easier to type on my german keyboard as well).

        And, from my personal view, i always associate ~ operations with some kind of regular expression stuff, whereas ? does not.

        "You have reached the Monastery. All our helpdesk monks are busy at the moment. Please press "1" to instantly donate 10 currency units for a good cause or press "2" to hang up. Or you can dial "12" to get connected directly to second level support."
Re: What operator should perl5porters use for safe dereferencing?
by BrowserUk (Pope) on May 29, 2012 at 14:01 UTC

    I voted for the first option because I think it is mnemonic, but some of the others are also

    • ~>: (hand)wavy deref.
    • ?> & ?->: questionable deref. (With a preference for the shorter.)

    With ->? it looks like the test comes after the deref.

    +> & !> just look like typos.

    ->-> looks like a double deref, rather than a single conditional one.

    I find all those using & anti-mnemonic in that elsewhere it takes a reference, rather than dereferences one.

    And those containing = look much too much like a fat comma. The parser may be able to distinguish them, but I don't think my brain would.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

    The start of some sanity?

      Interesting
       -> $rock->()->the->kasbah(); $rock->  ()->  the->   kasbah();
       ~> $rock~>()~>the~>kasbah(); $rock~>  ()~>  the~>   kasbah();
       &> $rock&>()&>the&>kasbah(); $rock&>  ()&>  the&>   kasbah();
       ?> $rock?>()?>the?>kasbah(); $rock?>  ()?>  the?>   kasbah();
       +> $rock+>()+>the+>kasbah(); $rock+>  ()+>  the+>   kasbah();
       !> $rock!>()!>the!>kasbah(); $rock!>  ()!>  the!>   kasbah();
       ->> $rock->>()->>the->>kasbah(); $rock->> ()->> the->>  kasbah();
       ->-> $rock->->()->->the->->kasbah(); $rock->->()->->the->-> kasbah();
       ==> $rock==>()==>the==>kasbah(); $rock==> ()==> the==>  kasbah();
       ?-> $rock?->()?->the?->kasbah(); $rock?-> ()?-> the?->  kasbah();
       ->? $rock->?()->?the->?kasbah(); $rock->? ()->? the->?  kasbah();
       &-> $rock&->()&->the&->kasbah(); $rock&-> ()&-> the&->  kasbah();
       &&-> $rock&&->()&&->the&&->kasbah(); $rock&&->()&&->the&&-> kasbah();
       -&> $rock-&>()-&>the-&>kasbah(); $rock-&> ()-&> the-&>  kasbah();
       -&&> $rock-&&>()-&&>the-&&>kasbah(); $rock-&&>()-&&>the-&&> kasbah();
       ->& $rock->&()->&the->&kasbah(); $rock->& ()->& the->&  kasbah();
       ->&& $rock->&&()->&&the->&&kasbah(); $rock->&&()->&&the->&& kasbah();
       -=> $rock-=>()-=>the-=>kasbah(); $rock-=> ()-=> the-=>  kasbah();
       =-> $rock=->()=->the=->kasbah(); $rock=-> ()=-> the=->  kasbah();
       ?> $rock?>()?>the?>kasbah(); $rock?>  ()?>  the?>   kasbah();
       ?-> $rock?->()?->the?->kasbah(); $rock?-> ()?-> the?->  kasbah();
       ?->: $rock?->:()?->:the?->:kasbah(); $rock?->:()?->:the?->: kasbah();
       ~>: $rock~>:()~>:the~>:kasbah(); $rock~>: ()~>: the~>:  kasbah();

        That seals it for me. ~> it is.

        Everything else just looks like an ant with the squits ran across the page even when you add a few spaces.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

        The start of some sanity?

        Wow, amazing what a difference actual examples make!! Visually, ~> is the clear winner. Thanks for making the chart!!

        Elda Taluta; Sarks Sark; Ark Arks
        My deviantART gallery

        That eliminates ~> as far as I'm concerned. Way too similar to ->.
      If it's mnemonic, what does it remind you of?
      • =~ match
      • $~ $FORMAT_NAME
      • ~~ smart match
      For me, Tanktalus' argument about the typing is more convincing than a mnemonic argument.


      - Boldra
        If it's mnemonic, what does it remind you of?

        I did say: "(hand) wavey dereference".

        As for your examples $fred~>$bill looks nothing like $str =~ $re; or when $ref ~~ @things:.

        I'm not sure if that last example is valid syntax. I've never user smart matching in real code. I've tried it a few times when I thought it might work for me, but it either didn't do what I thought it would or gave a syntax error. I don't try any more.

        And as for $~, it not only looks completely different to ~>, I've never seen it used in code outside of its own documentation; and possibly obfu.

        A more poignant example might be something to do with boolean negation: ~$mask, but I tried and couldn't think of a single valid expression that looked vaguely similar.

        For me, Tanktalus' argument about the typing is more convincing ...

        "touch typists" who find things 'difficult to type' drive me nuts. The only people I've ever seen reach touch tying speeds when typing code, were copy typists.

        Programmers on the other hand, type a few symbols; pause; back up and change the variable name; pause; change it again; back up two lines and change the if to a while; then switch screens and look up an API; switch back and undo the last set of changes and start over...

        'sides, on my keyboard, it is left-shift '.', left-shift '#'. Easy :) Now if I could change the scalar sigil from $ to , that would save me having to correct at least one Unrecognized character \xA3 in column 4 at... in just about every piece of new code I type.

        For me the strongest argument against it is that it looks so similar to ->. But actually, given its purpose, I even consider that a strength. Most of the time, the subtle difference will be completely transparent semantically and the subtle visual difference reflects that. Ie. It doesn't demand undue attention.

        And for those occasions when the difference is important; the code immediately following will have to reflect the fact that an undefined reference may exist.


        But in the end, someone, somewhere will make a decision based upon some reasoning, and it will satisify some and not others.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

        The start of some sanity?

        if we talk about mnemmonic rules...

        if you want to be safe "go to the hospital"

        +>

        But I must admit that is much less readable

Re: What operator should perl5porters use for safe dereferencing?
by ForgotPasswordAgain (Deacon) on May 29, 2012 at 14:21 UTC
    Does "None" include making -> do this already itself?

      I'm not sure that the usage would be common enough. A lot of the time, you'd want to know and fix the problem.

      Perhaps have -> do safe dereferencing, but throw a warning?

      Yes, and that's an alternative that's been proposed (by me and independently by others). The consensus is that it could be done using autobox. That's my personal preference, with the option to turn off a warning for it:
      $z = $not_defined->arbitrarymethod() Method not called at ...
      I personally think that's preferable to a whole new operator; the idea is to make it work in much the same way that sending messages to nil does in Objective-C: it does nothing, and returns nil (which equivalences to 0 in numeric context). For Perl, it'd do nothing and return undef (in list context it'd return an empty list).

        The thing is, I would want to use this in a scope as limited as possible. Which means I would end up with:

        my $object = $other_object->get_object; my $result = do { use safederef; $object->possible_method; };

        At which point I could basically write

        my $object = $other_object->get_object; my $result = $object ? $object->possible_method : undef;

        Which would mean we'd end up with a best-case scenario where the traditional way needs less code to provide the same. Compare this to:

        my $result = $other_object?->get_object?->possible_method;

        Ordinary morality is for ordinary people. -- Aleister Crowley
        I've been using Perl for a while and with Perl's 'do what you want' it would seem that there shouldn't be a new operator. Returning undef seems fine with a warning
Re: What operator should perl5porters use for safe dereferencing?
by Tux (Monsignor) on May 29, 2012 at 14:32 UTC

    My pref is ~>, but ?-> follows close. All others get my no.


    Enjoy, Have FUN! H.Merijn
Re: What operator should perl5porters use for safe dereferencing?
by vendion (Scribe) on May 29, 2012 at 14:44 UTC

    I dislike the three character evaluations in PHP such as === or !== while I understand their importance to the language (I also know this isn't about PHP) I still don't like them. I would be fine with something like ~> for this.

Re: What operator should perl5porters use for safe dereferencing?
by temporal (Pilgrim) on May 29, 2012 at 14:53 UTC

    Voted ~>

    It looks enough like the classic operator to make sense intuitively and tilde seems to mean "do the smart/more flexible thing" in my mind.

    However, I do like the idea of +>

    Like we incremented the operator, ha. Too bad it isn't that readable.

    Strange things are afoot at the Circle-K.

Re: What operator should perl5porters use for safe dereferencing?
by thomas895 (Hermit) on May 29, 2012 at 15:22 UTC

    I voted None because the -> makes more sense, and you should always use Safe and strict ;-)

    ~Thomas~
    I believe that the source code to life is written in Perl :-)
      I am curious what relevance you think Safe has, and why you would consider a deprecated module mandatory?

      Update: oh, maybe it is not deprecated.

      ---
      alter ego of demerphq

        Safe, while perhaps not the best example, does allow execution without the risk of your program dieing. I guess it's for the folks who have something against eval.

        ~Thomas~
        I believe that the source code to life is written in Perl :-)
Re: What operator should perl5porters use for safe dereferencing?
by davido (Archbishop) on May 29, 2012 at 18:17 UTC

    We have the // and //= operators which work like a 'defined' short circuit, otherwise emulating || and ||=.

    On your list of options I don't see ones that kind of stand out as being of similar encoding: //->, and -//>

    The concerns are that they start looking like the closing side of a markup tag, and that the version I like the most would become Perl's only four-contiguous-character non-alpha operator (that I can think of).

    What I don't like with respect to any of the ~ options is that they feel like they should be doing some form of matching: pattern, smart, or even dereferencing-lookup matching (which is what -> already does as it scans the inheritance tree).


    Dave

      My thoughts, exactly. If such a beast were to arise, I would prefer that it be somewhat consistent (visually) with defined-or (even though we are trying to represent defined-and). I might be persuaded that something based on && would be suitable.

      IMO, many of the poll options resembled bitwise operations, matching, and the ternary operator too strongly.

      That was my first hunch too, being a huge fan and user of the defined-or operator, but using that here would have been the opposite of what is required. What is suggested is a defined-and operator, which does not (yet) exist. For me that indeed rules out //-> and -//>. Think about it again when defined-or would be used :)


      Enjoy, Have FUN! H.Merijn
Re: What operator should perl5porters use for safe dereferencing?
by tobyink (Abbot) on May 29, 2012 at 18:41 UTC

    I think the question-mark ones probably seem like they'd be most intuitive. We're already familiar with "?" from the ternary operator; and if you use one of the many CPAN modules providing method signatures, the question mark is often used to indicate optional parameters.

    That said, the ~> looks less ugly in real code, so overall I prefer that.

    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: What operator should perl5porters use for safe dereferencing?
by DrHyde (Prior) on May 30, 2012 at 10:11 UTC

    A serious poll? What's happened? Has perlmonks been taken over by the lizard people?

    I voted "none", because I believe this would not be a good idea. Attempting to dereference something that isn't a reference is a sign that you've done something wrong and that you have a bug - maybe you passed the wrong parameter to a function, or you forgot to check a return value. Papering over the cracks will just make your code harder to debug.

Re: What operator should perl5porters use for safe dereferencing?
by dsheroh (Parson) on May 30, 2012 at 10:36 UTC
    First gut reaction was ~> but, on further reflection, I decided that it's a bad match (no pun intended) for the normal meaning/behavior of ~ in Perl. =~ is a regex match and ~~ is a smart(ish) match, but this "safe dereference" isn't doing any kind of matching at all.

    So I ended up voting for ->> because it's the same as the normal dereferencing operator, modulo a key bounce, making it quick to type. I think --> would have been more aesthetically pleasing than ->>, plus the added character is non-shifted which makes it a little more convenient to add/remove while debugging/testing, but it wasn't on the list of options.

    My real preference, though, would be for -> to do a safe dereference by default, optionally with a warning. (Personally, I'd prefer any warning to only be enabled if explicitly requested, not just by a blanket use warnings or perl -w, but I recognize that this would be inconsistent with current warnings.) Given how often I find myself writing things like if ($foo->bar && $foo->bar->baz) {...}, I have to disagree with the earlier comment saying that if any link in that chain is undef, then you obviously have a problem - it's entirely possible that $foo may simply not have a bar and that's that.

Re: What operator should perl5porters use for safe dereferencing?
by Arunbear (Parson) on May 30, 2012 at 10:39 UTC
    I prefer ?-> because it makes it clear that there might not be a receiver for the message send ->, much more than ~> which suggests that some kind of pattern or smart match is involved. In the Groovy language, they call it the Safe Navigation Operator e.g.
    def streetName = user?.address?.street

      I do not personally care for ?-> because it reminds me of the ternary operator.

      I voted for ~> due to terseness & the implication of flexibility



      Wait! This isn't a Parachute, this is a Backpack!
Re: What operator should perl5porters use for safe dereferencing?
by ikegami (Pope) on May 30, 2012 at 16:01 UTC
    I wish this was done outside of core first so we don't end up with another smart-match fiasco. (Upd: Especially since there are already dissenting opinions on what it should do.) Not sure how that's possible unless it's done through pragmas instead of syntax.
Re: What operator should perl5porters use for safe dereferencing?
by talexb (Canon) on May 30, 2012 at 20:35 UTC

    I like ?> because the '?' introduces uncertainty. The choices ?-> and ->? are good in that they include the already familiar arrow shape .. but they are one more keystroke. Of the two, I like the second one -- a) call the method, b) did it work?

    Alex / talexb / Toronto

    "Groklaw is the open-source mentality applied to legal research" ~ Linus Torvalds

      Of the two, I like the second one -- a) call the method, b) did it work?

      Hm. That's backward. How can you call the method if you don't have a valid reference?

      Of those two, I prefer the first: a) do we have a valid reference? b) if so, dereference it.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

      The start of some sanity?

        You're quite right, I do have it backwards. Bother.

        Alex / talexb / Toronto

        "Groklaw is the open-source mentality applied to legal research" ~ Linus Torvalds

      ->? is my favourite too, and the extra keystroke is preferable to the shift-swapping needed for ~> (you could count the shift-swap as an extra keystroke). > and ? are next to each other on my keyboard, so the extra typing effort is minimal.


      - Boldra
Re: What operator should perl5porters use for safe dereferencing?
by Neighbour (Friar) on May 31, 2012 at 08:12 UTC
    None. I agree with pemungkah Re^2: What operator should perl5porters use for safe dereferencing?.
    On a side note, I don't agree with Tanktalus' touch-typing skills. According to touch-typing rules, if you have to type a shifted character with your left hand, you have to use the right shift (and vice versa). This would mean holding the right shift (with your right pinky), while typing the ~ with your left ring finger, and then switching shifts (which is almost never done) and typing > with the right ring finger. Alternatively, you could hold the right shift and type > with the right middle finger.
Clarify what it does
by Boldra (Deacon) on May 31, 2012 at 08:48 UTC
    It would make $bar-XX>method() safe if $bar is undefined, but what if $bar is a scalar? Or an unblessed reference? Or an array ref? or a coderef? Would the same operator work for fetching elements of array refs and or keys of hashrefs, or only for methods?


    - Boldra
      It would make $bar-XX>method() safe if $bar is undefined, but what if $bar is a scalar? Or an unblessed reference? Or an array ref? or a coderef?
      The poll question specifically states it's for attempting to call methods on undef. I'm fairly certain that it's not intended to gloss over attempts to call methods on arbitrary scalars and especially not on references of the incorrect type. Those should definitely remain errors.
      Would the same operator work for fetching elements of array refs and or keys of hashrefs, or only for methods?
      Interesting thought... It would make sense to me, at least, that if an arrayref/hashref is undef, then all of its elements are implicitly undef as well.
Re: What operator should perl5porters use for safe dereferencing?
by zwon (Monsignor) on May 31, 2012 at 12:30 UTC

    As Abigail noted in p5p, ~> in some terminals doesn't look good at all. It mine it looks more like ~>

      1. How much time do you spend reading or editing code in a terminal session?
      2. You could grab yourself a descent programmer's font and use it in your terminal sessions.

      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

      The start of some sanity?

        How much time do you spend reading or editing code in a terminal session?

        100% of time

        descent programmer's font

        I find terminus quite decent. And I don't think that requirement to use font that have tilde in the middle of the line in order to read the code is reasonable.

Re: What operator should perl5porters use for safe dereferencing?
by xiaoyafeng (Chaplain) on Jun 01, 2012 at 02:46 UTC
    I vote to ?->, perl is a sigil language, and keep them consisting. I think ~ is assigned to regex match already?




    I am trying to improve my English skills, if you see a mistake please feel free to reply or /msg me a correction

      I think ~ is assigned to regex match already?

      No, see perlop

      Binary "=~" binds a scalar expression to a pattern match. Binary "!~" is just like "=~" ... Binary "~~" does a smart match between its arguments. Unary "~" performs bitwise negation ""->"" is an infix dereference operator, just as it is in C and C++. nonassoc < > <= >= lt gt le ge
      so currently  ~> is a syntax error, you can't have unary operator bitwise-negation follow greater than operator, so  ~> is free and open for use with no possibility of confusion with anything else

      Also, neither  > nor ~ nor ~> nor -> are sigils, sigils are  $ % @ * as in  $ro %sham @bo *dynamite

        Thanks for your correction! But the 3 first main usages of ~ is about match. I suggest ?-> is I believe the one of advantages which perl6 is better than perl5 is its consistency. take a look below:
        • ~ means string, so ~$foo change $foo into string context, and $foo1 ~ $foo2 make a concatenation.
        • +/- means numeric, so +$foo change $foo into numeric context and $foo + 3 is doing mathematic operation.
        • and ? means bool, * means global etc.......
        as we see, in perl6, every sigil has its own consistent meaning and easily for learning. I don't say ~> is bad, I just want every new grammar/op adding during perl5 evolved should keep consistent.




        I am trying to improve my English skills, if you see a mistake please feel free to reply or /msg me a correction

Re: What operator should perl5porters use for safe dereferencing? (&-> and ->?)
by tye (Cardinal) on Jun 01, 2012 at 05:52 UTC

    I find ~> not visually distinct enough (otherwise, it might be my first choice). [Update: Alternately, in some fonts it doesn't even look like an arrow and so reads more like "approximately greater than". The combination of the two possible presentations makes it a particularly bad choice, IMHO.]

    The name "safe de-ref" means more to me than what is being proposed here. What is being proposed is merely the more specific "undef-safe de-ref". As such, the closest representation of what it does is the &&-> choice (a syntax which I'm pretty sure I've seen in some other language, though I don't recall which).

    However, it isn't actually &&-> so I'd vote for &-> because it is that much less ugly and is mnemonic for "slightly different from &&->". In case some don't quite follow... If we had an operator that was to "&&" as the new "//" is to "||", then that operator would be the ideal one to paste in front of "->" to get this new "undef-safe de-ref" operator. But we don't. Now, "&&->" naturally implies "de-ref if true" which is only slightly different from "de-ref if defined". So "&->" is about as close as we can get to "de-ref if defined" by virtue of being "slightly different from 'de-ref if true'". But we do have "&" so you could interpret "&->" as "bit-wise 'and' then de-ref" but that just makes no sense.

    So my choice would be for "&->". But part of my reason for that choice (despite it being somewhat ugly) is because I would also like to have something worthy of being called "safe de-ref".

    I'd like to also have "->?" added to Perl 5. Since "safe de-ref" is too vague, we should call "->?" the "de-ref if possible" operator.

    So $obj->?blurg(@args); would be roughly equivalent to $obj->blurg(@args) if $obj->?can("blurg"); (note how I had to use "->?" in order to safely call can() on something that might be neither an object nor a class).

    But my hopes for "->?" are even better realized if, in the process of extending Perl 5's de-ref operators, we also add the long-ago-proposed de-ref operators of "->@" and "->%". Because "is this a hash reference?" is a complete mess in Perl 5.

    It started with ref which had the poor design of not thinking blessed hash refs are hash refs. Then we added ->isa("HASH") which was more accurate in several ways but rather sucked because you can't safely call ->isa(...) on some random scalar. Then chromatic's fetish for forcing everybody else to do things his way so he wouldn't have to make a minor improvement to his used-only-in-testing module got pushed as a moral stance against making isa actually convenient as well as useful so that problem just gets worse. So I've resorted to things like eval { $ref->{''} } but that gets unacceptably complicated because you might have a version of Perl that issues warnings (not suppressed by eval) when you do something that it thinks might be an attempt to use the deprecated "pseudo-hash" feature.

    So $ref->?% or even defined $ref->?% would be a nice replacement for all of the prior "is a HASH?" techniques. It'd even work for blessed references to scalars that overload hash de-ref'ing.

    And even if we don't get ->%, I'd still be happy to have $ref->?isa("HASH") which I don't believe would violate chromatic's edicts about how I should be allowed to use isa() (but would require overload to properly either fudge @ISA or override isa() when an object overloads a data de-ref operation if we want ->?isa to be completely accurate).

    And, of course, you could do things like:

    $opt = $ref->?{optName} // $ref->?[optNumb()] // ref->?();

    for when you don't really care which succeeded or why and you just want the result (or undef).

    Thanks much to Tanktalus for helping me with these ideas.

    Update: I'd also be happy with just implementing ->? (but my guess is that many will want "de-ref if defined" w/o having to also silently ignore the extra "de-ref isn't possible" cases). But I'd be quite sad if ->? were used to implement just "de-ref if defined".

    - tye        

      I also strongly support the "make plain -> to be undef-safe" position. I've long found it frankly a design bug that using strict.pm means that $undef->{key} will either 1) silently create a hash or 2) die (depending on often-subtle issues of context).

      My preference would be more like: Let me pick how de-ref'ing an undef behaves from 1) silent, 2) warn, or 3) die. Then, depending on my choice, $undef->{key} would pick (depending on context) between these paired choices of behaviors:

      1. a) silently auto-vivify or b) silently return undef
      2. a) auto-vivify with a warning or b) return undef with a warning
      3. a) die or b) die

      But, as a transition, it would be great if a future version of Perl 5 had default behaviors of:

      1. w/o 'use strict': a) silently auto-vivify or b) silently return undef
      2. w/ 'use strict': a) silently auto-vivify or b) return undef with a warning

      (for extra clarity, 2b would be the only change.)

      I almost always 'use strict;' and I almost always want $x = 'y'; $x->{z} to be fatal. But I very often don't want this to die:

      sub routine { my( $arg, $opt ) = @_; blarg( $arg ) if $opt->{blargTheArg}; ... }

      So I've gotten in the habit of writing ( $opt || {} )->{blarg} (after too many cases of code making it into Production before it ran into a case that resulted in $opt being undef).

      So, it will be less work to form a habit of $opt&->{blarg} (or $opt->?{blarg}), but I'd much rather be able to declare that undef-> triggers a warning (in either context) and to have that be the default behavior in the context where the current behavior really just doesn't make a lot of sense.

      On a side note, yes, I am aware of the autovivify module. I've long wanted that capability but I have no plans of using that module because the amount and complexity of XS code contained in it seems like a very inappropriate way to implement this feature (except as an experiment / proof of concept before it can be accepted into the 'core' -- which is what I consider this module) and has too high a risk of bizarre failures for the benefit provided, in my experience. I expect that one day the too-much and too-complex XS code of autovivify.xs will be completely replaced by some quite simple 'if' statements that examine 'hint bits' being sprinkled into a few places in Perl's own de-ref-implementing code and then I'll have a 'no autovivify;' that I can feel safe using.

      Even better will be if the way that I declare 'de-ref'ing undef in an lvalue context generates a warning' at least can also declare the same (or similar) behavior for rvalue contexts.

      - tye        

        I don't think I'd have a big issue with this applying to hash and array refs. but ignoring method calls on undef by default is a big No-no for me. I'd definitely vote for it being a completely separate pragma then.


        Ordinary morality is for ordinary people. -- Aleister Crowley
Re: What operator should perl5porters use for safe dereferencing?
by ambrus (Abbot) on Jun 02, 2012 at 13:03 UTC

    NOOOO!

    I want &-> because it's so understandable. People who haven't seen it would be able to guess what it does. That won't happen with ~> .

      Interesting - in contrast to your statement, I didn't understand the relevance of the ampersand until the very end of the discussion thread here and found its inclusion in the poll puzzling. I didn't read it as $bar *AND* call method method() on $bar; instead, I read it as the C "address-of" operator. Goes to show that what may seem understandable and intuitive to one person may not be at all for another.

        I guess you're right, the ampersand isn't so obvious.

        The problem is, reading the ampersand meaning address of could even make sense in perl. You could want an operator to create a bound method call, so eg. $object&->method creates a bound method like do { my $o = $object; sub { $o->method(@_); } }, and $object&&->method creates a bound method call weakly referencing the object.

Re: What operator should perl5porters use for safe dereferencing? (Specification?)
by LanX (Canon) on Jun 02, 2012 at 13:50 UTC
    I'm confused!

    The poll is bout calling methods on undef instead of a blesses ref, the linked p5p discussions I read so far are about avoiding autovivication when dereferencing nested var-refs.

    So which cases are covered?

    Cheers Rolf

      Both of those!

      $r&->f would behave something like $r && $r->f so it would call method f on the object $r if it's set, or do nothing and return undef if $r is undefined.

      $h{$w}&->() would look the word $w up in the hooks table %h, and if there's an entry, call it as a subref, but if there's no entry, it would just nop silently.

      Finally, $t{$x}&->{$y} would be like $t{$x}{$y} only it doesn't autovivify $t{$x} as a hashref if it doesn't exist.

Re: What operator should perl5porters use for safe dereferencing?
by snoopy (Deacon) on Jun 04, 2012 at 02:35 UTC
    I'm also going with ~>. Visually the squiggle (tilde), to me, looks like a "tentative dereference".

    Btw, I really can't wait. I'll be able to pull horrible hacky code such as:

    package MyApp::Universal; use warnings; use strict; use Try::Tiny; sub deref { # # Weak linear dereferencing. $foo->deref('bar','baz') # is almost like $foo->bar->baz except we'll # return undef rather than barfing if 'foo' # or 'bar' evaulate to undef. # if (@_ >= 2) { my $ref = shift; my $deref = shift; return unless defined $ref && defined $deref && try {$ref->can('isa')}; return deref($ref->$deref => @_); } elsif (@_) { return shift; } else { return; } }
    They I can go through my code and refactor....
    $obj->deref(qw(foo bar baz));
    as....
    $obj~>foo~>bar~>baz;
    Update Also look forward to be able to do...
    $href~>{foo}~>[$bar]~>{baz};
    ...when I don't want autovivification.
Re: What operator should perl5porters use for safe dereferencing?
by ysth (Canon) on Jun 04, 2012 at 16:57 UTC
    Err, shouldn't this just be -//>?
    --
    A math joke: r = | |csc(θ)|+|sec(θ)|-||csc(θ)|-|sec(θ)|| |
      That's valid syntax. "Is the negation of the match result greater than ..." That might not be a problem, though.

      -//> would be "de-ref if undefined" while what is being proposed is "de-ref if defined".

      - tye        

Re: What operator should perl5porters use for safe dereferencing?
by LanX (Canon) on Jun 07, 2012 at 21:45 UTC
    after some days of thoughts an digestion I'd really prefer ->>

    Not only because it's easy to type, it's close enough to -> be easily read and understood as an extension for a special case

    This follows the same approach like == and === in JS, where repetition indicates a specialization.

    ~> looks nice at first glance, but is too easy to be overlooked in some fonts and at the moment I have to deal with too many low level Perl users who wouldn't spot it.

    ?-> or &-> might have a derivable logic, but look too much like line noise.

    And it's not very consequent to allow &-> if we are sure that there will never be a |-> or !->.

    Cheers Rolf

      I voted on ~> but now I agree with you, ->>
        I voted on ~> ...

        Unfortunately, me too.

        Cheers Rolf

Re: What operator should perl5porters use for safe dereferencing?
by pvaldes (Chaplain) on Jun 13, 2012 at 11:09 UTC

    mmmh, I think that I had an interesting idea...

    This is a safety kit:

    http://www.shoestringmag.com/files/images/main/DIY_Emergency_Kit.jpg

    Is iconic, simple and universally understood

    So what if instead something like ~> we consider something like [+]>?

    We could to teach emacs or vim to print this 3 chars in red so is more readable that other options and thus you can't mistake for a part of a sum, is a red cross in a box, everybody can catch this idea in seconds

    If you want SAFE dereference simply add a safety kit "[+]" to your code:

    I don't know if this could horribly crash with another internal or external perl structures (don't think that the combo [+]> should be frequently seen in a regex anyways) but looks a simple, elegant, easy to remember and strong concept to me, and not to much ugly to read, specially if we use an editor that can print this 3 characters in red if found before a ">".

     [+]>     $rock->()->the->kasbah();     $rock[+]>  ()[+]>  the[+]>   kasbah();

    What dou you think about it?

Re: What operator should perl5porters use for safe dereferencing?
by frozenwithjoy (Curate) on Jun 16, 2012 at 06:59 UTC
    I'm really surprised to see ~> get the most votes. It is quite difficult to distinguish from -> without putting my face close to the screen and my mom always yelled at me for sitting too close to the tv, so I'll probably have anxiety attacks if ~> is chosen...
      font.monospace=font:DejaVu Sans Mono,size:11

        My concern isn't so much how it looks in my editor, but everywhere else. I doubt the internets are going to change their fonts just for us. Hopefully Perlmonks would, because that's where I was looking when trying to distinguish.

        In fact, look at this: ~ <---- without code markup

        and this: ~ <---- with code markup

        Without increasing my font size, I can just barely tell that the tilde is a tilde without the code markup. With the code markup, it is hopeless.

        In the event that it is easily distinguishable for you, here is a screenshot of this entry on OS X; Chrome; View:Actual Size.

Re: What operator should perl5porters use for safe dereferencing?
by uday_sagar (Scribe) on Jun 19, 2012 at 09:22 UTC

    I would go for:

    -)

    what say guys?

Re: What operator should perl5porters use for safe dereferencing?
by Anonymous Monk on Jun 22, 2012 at 11:51 UTC
    I don't want there to be such an operator, because I want errors warned about as early as possible. I know the existing behaviour has many faults, but I still don't think the introduction of this operator is an improvement.
      I'm surprised at the number of lazy answer types on here "~>"? "~" is used in the context of binary NOT, or pattern matching. Neither has anything to do with conditional pointer referencing. you want to choose something, ideally, that makes sense in the language.

      Going from it being a conditional expression, the idea of a question mark naturally comes to mind as in a conditional statement like "x?a:b", here, you are questioning if the pointer is valid, if yes, do "->", implicitly, in the no case, the answer is "undef", so the ":undef part becomes superfluous. So "?->" seems clear to me.

      While it is in 2nd place, it's amazing how laziness outranks logic almost 3:1 -- (more general population would probably choose lazy over logical 10:1 I'd bet...)

        Excellent argument! You can diddle my perl anytime perl-diddler!
        "~" is used in the context of binary NOT, or pattern matching. Neither has anything to do with conditional pointer referencing

        '-' is used in numeric subtraction; '>' is used in numeric greater than; both are used in numeric comparison <->.

        Neither has anything to do with pointer dereferencing -> .... D'oh!

        (You cannot break multi-character operators into bits to try and make sense of them!)

        ~> isn't just(*) the lazy option; it is also the logical option.

        The subtlety of the difference in the operators reflecting well the subtlety of the difference in the operation (note:singular) they perform.

        Ie. They both do the same thing -- dereference a pointer. The subtlety is that the new operator doesn't blow up if the variable it is applied to contains undef rather than a reference.

        Most of the time when scan reading the code; that subtlety will be unimportant. And when the difference becomes important, the code following the new operator will need to deal with its consequences and that will be more than sufficient to demarcate its use.

        *laziness -- the desire to not have to constantly type unnecessary boilerplate verbiage -- is a virtue in a programmer.

        It is why Perl programmers infinitely prefer to type:

        #! perl -slw use strict; print "What's your name? "; print 'Hello ' . <STDIN> . '!!!';

        Rather than

        import java.io.IOException; import java.io.InputStreamReader; public class HelloName { public static void main(String[] args) throws IOException { System.out.println("What's your name? "); // the BufferedReader is able to store some data for easier retrie +val BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(System.in)); String name = bufferedReader.readLine(); System.out.println("Hello " + name +"!!!"); } }

        I mean, honestly is it so good it needs to be said thrice? : BufferedReader bufferedReader = new BufferedReader(

        Even the damn comment is grievously wrong!


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

        The start of some sanity?

Re: What operator should perl5porters use for safe dereferencing?
by mantager (Sexton) on Jun 27, 2012 at 13:05 UTC

    OMG ~> rmakes me think to PANG!

      Exactly! It is almost impossible to see it as anything other than a wiggly arrow. Ie. A hand-wavey dereference :)


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

      The start of some sanity?

Re: What operator should perl5porters use for safe dereferencing?
by raybies (Chaplain) on Jun 28, 2012 at 13:20 UTC
    ...of course even if ~> wins, to make it a true Perl operator we'll need to have the ~> do more than just safe dereferences, we'll need it to do a dozen other things too... so we should have a new poll with suggestions on alternative things the ~> operator can do besides just safe derefs... :)

View List Of Past Polls


Log In?
Username:
Password:

What's my password?
Create A New User
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (9)
As of 2014-07-14 08:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    When choosing user names for websites, I prefer to use:








    Results (257 votes), past polls