in reply to Re^2: Mr. Ternary is greater than Mrs. If Else
in thread Mr. Ternary is greater than Mrs. If Else

yes, readability at first is a problem with Mr. Ternary... i can't get wrong with that... but as often you use the ternary operator becomes handy. but wait my delima was this "\&". what was that execption for in the strict pragma?

I think it is your dilemma, and yes: I had never seen it. Indeed, had you asked me, I would have guessed it was no valid syntax at all. And while I'm far from being a guru myself, I've seen quite a lot of code over the years, from gurus too. However reasoning on it a little, it's easy to see it simply amounts to taking a real reference after taking a symbolic dereference. The exception perldoc strict talks about is that that particular symbolic dereference, in that situation, doesn't issue an error, while it would in all the other situations:

C:\temp>perl -wMstrict -e "\&{'foo'}" Useless use of reference constructor in void context at -e line 1. C:\temp>perl -wMstrict -e "&{'foo'}" Can't use string ("foo") as a subroutine ref while "strict refs" in us +e at -e line 1.

Why you think you can use that instead of eval is completely out of my comprehension. The semantics is completely different.

Replies are listed 'Best First'.
Re^4: Mr. Ternary is greater than Mrs. If Else
by shmem (Chancellor) on May 19, 2007 at 19:12 UTC
    Consider
    perl -le 'use strict; my $foo = 1; $foo ? \&{print "foo"} : \&{ print +"bar"};' foo

    Inside a ternary ?: the expressions are evaluated - and \& { } constructs a code ref block which gets evaluated at runtime, to get at the name of the symbol table entry CODE slot from which a reference is taken.

    perl -MO=Concise,-exec -le '$foo = 1; $foo ? \&{print "foo"} : \&{ pri +nt "bar"};' 1 <0> enter 2 <;> nextstate(main 1 -e:1) v 3 <$> const[IV 1] s 4 <#> gvsv[*foo] s 5 <2> sassign vKS/2 6 <;> nextstate(main 3 -e:1) v 7 <#> gvsv[*foo] s 8 <|> cond_expr(other->9) vK/1 9 <0> pushmark sRM a <0> pushmark s b <$> const[PV "foo"] s c <@> print sK d <1> rv2cv[t3] lKRM/AMPER,33 <---- here e <1> refgen vK/1 goto f g <0> pushmark sRM h <0> pushmark s i <$> const[PV "bar"] s j <@> print sK k <1> rv2cv[t4] lKRM/AMPER,33 <---- and here l <1> refgen vK/1 f <@> leave[1 ref] vKP/REFC -e syntax OK

    <update>

    For the bare \& { } try e.g.

    perl -le 'use strict; my $foo = \&{ print "bar"}; $foo'

    </update>

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
      Inside a ternary ?: the expressions are evaluated - and \& { } constructs a code ref block which gets evaluated at runtime, to get at the name of the symbol table entry CODE slot from which a reference is taken.

      This literally answers my question, and indeed I had realized myself after posting. Anyway I would consider this the "most side-effectish hack abuse one may have imagined for such a thing". This is certainly silly: one thing either has side effects or not, but... well to mangle the sybol table just to execute a block is... err... well... just as bad™ as I can imagine!

Re^4: Mr. Ternary is greater than Mrs. If Else
by PerlPhi (Sexton) on May 19, 2007 at 18:46 UTC

    well first of all im not that good in understanding english terms that are so deep for me. but then let me rephrase your question... well correct me if im wrong... maybe you were asking me that, why did i use "\&" instead of eval, and because they have different functions right?

    my answer would be as follows:

    a couple of hours ago i was trying (tweaking) to make Mr. Ternary operator work on multi-statements. i tried a sub function definition inside the ternary but it didn't succeed, and so on and so forth. until i came up with that compilation error "Can't use string ("1") as a subroutine ref while "strict refs" ....". so i checked the documentation right away and found that exception in strict pragma "\&". but i didn't make use of it immediately instead i tried to use the eval block. since the eval block is just a single statement that can be used as a container of my multi-statements to function in Mr. Ternary. then, it succeeded. next is i tried to use the "\&", replace the word "eval" with that, and it worked well.

    so to wrap up my observations between "eval" and "\&":

    "\&" - is used while bullet proofing a program because it permits runtime error to exit my program so sudden. so the programmer could easily notice the error.

    "eval" - is used when you have finished bullet proofing a program. well it just trap runtime errors that was not caught by the programmer.

      "\&" - is used while bullet proofing a program because it permits runtime error to exit my program so sudden. so the programmer could easily notice the error.

      "eval" - is used when you have finished bullet proofing a program. well it just trap runtime errors that was not caught by the programmer.

      <update>

      No, the difference is that \& { } constructs a reference to a subroutine which is named after whatever it is the evaluation of the contents of { } returns. That is, \& {chr(65)} returns a reference to the subroutine A, be this sub defined or not. In your example, a subroutine is allocated in the symbol table named after the return value of exit or yes\n, depending on the input. Which is a weird form to shoehorn something into the symbol table.

      </update>

      <No, the difference is that \& { } constructs a code reference from a block (which isn't even a subroutine, just a code reference) which is a reference to a subroutine , while eval { } ... well, evals the { } block. So, \& { } is just bare metal, without the additional features eval { } provides.

      One could say \& { } is to eval { } what do is to require, if that helps (it's not quite so).

      I don't know the compile time implications of \& { }, but I suspect them to be the same as with eval { } - this all isn't about bullet proofing, but - again - I might be wrong.

      --shmem

      _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                    /\_¯/(q    /
      ----------------------------  \__(m.====·.(_("always off the crowd"))."·
      ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

        oww...i see... even though i have just finished the "Llama Book" lately, and currently reviewing what i have learned before i read the "Intermediate Perl", i understood now that the "\&" block is just an ordinary block that is used to group a number of statements. okey, thats very helpful even though i have not yet come up with reading about reference.

        okey then, i will have to sleep for a moment because it is already 4:00 AM here in Philippines. i will check any replies when i wake up...

        thanks to everyone who have contributed. it is really a pleasure...

      "\&" - is used while bullet proofing a program because it permits runtime error to exit my program so sudden. so the programmer could easily notice the error.

      "eval" - is used when you have finished bullet proofing a program. well it just trap runtime errors that was not caught by the programmer.

      Nope, they're both "tricks" you're using to put several statements where only one would fit. Should I choose one such trick, it would be do. As far as eval is concerned: yes, you can use it to trap exceptions. That's the Perl 5 way to do so. It's a completely orthogonal matter. If you need that, just use it. If you don't, don't, whether it's in an argument to ?:, in an if block, in a sub... wherever!

      Update: \& is just one way to execute a block, indeed the most abusive one. As long as you're abusing something to do stuff it's not really meant to, you may have chosen:

      map { CODE } 1

      or

      grep { CODE } 1

      too.