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

Re^3: tk option+value in variable?

by cniggeler (Sexton)
on Jan 25, 2019 at 22:01 UTC ( [id://1228996] : note . print w/replies, xml ) Need Help??


in reply to Re^2: tk option+value in variable?
in thread tk option+value in variable?

Maybe this should be a nother top-level question, but can you tell me know you knew to promote my string to an array? I was playing with subroutines and arguments, and I found that all these generated the same answer (5):

my $a = 2; my $b = 3; print &add($a, $b) . "\n"; my $opt = "$a, $b"; print &add(eval($opt)) . "\n"; my @opt = ($a, $b); print &add(@opt) . "\n"; exit; sub add { my ($x, $y) = @_; return ($x +$y); }
Another area my knowledge is lacking is the dash notation for the options (-font => 'courier', for example); is that common in other areas of perl or specific to Tk?

Replies are listed 'Best First'.
Re^4: tk option+value in variable?
by choroba (Cardinal) on Jan 25, 2019 at 22:15 UTC
    Use split to split a string into a list.
    #!/usr/bin/perl use warnings; use strict; use List::Util qw{ sum }; my ($x, $y) = (2, 3); my $opt = "$x, $y"; my @opts = split /,\s*/, $opt; print sum(@opts);

    The dashes are just a convention. They were somehow common at the time Perl/Tk was created, so there might be other modules using them. See the explanation of "unary -" in perlop.

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
Re^4: tk option+value in variable?
by AnomalousMonk (Archbishop) on Jan 26, 2019 at 01:28 UTC
    ... [how] you knew to promote my string to an array?

    A subroutine such as your  add() can be called with an argument list; choroba just made the arguments you wanted to pass into an expression (specifically, an array) that would be accepted as a list expression by a subroutine call; see perlsub. (BTW: There's no need to use the  & sigil for a subroutine call. Indeed, you should avoid this syntax because it has some oddball effects; see especially the paragraph beginning 'A subroutine may be called using an explicit "&" prefix.' in the DESCRIPTION section of perlsub.) (Also BTW: IMHO it's not, in general, a good idea to use the variable names  $a $b as lexical names even in short example code; these are Perl special variables and have special significance and usage; see perlvar.)

    ... arguments ... all these generated the same answer ...

    I'll avoid using the  & sigil prefix in all discussion and examples.
        print add($a, $b) . "\n";
    Pass a list of two scalars (list elements are always scalars) to the  add subroutine.
        my $opt = "$a, $b";
        print add(eval($opt)) . "\n";
    First, eval the Perl string list expression  "$a, $b" and then pass the resulting list returned by eval to the subroutine.
        my @opt = ($a, $b);
        print add(@opt) . "\n";
    Expand an array to the argument list of a subroutine call.

    c:\@Work\Perl\monks>perl -wMstrict -le "my ($x, $y) = (2, 3); ;; print add($x, $y); ;; my $opt_dq = \"$x, $y\"; print add(eval($opt_dq)); ;; my $opt_sq = '$x, $y'; print add(eval($opt_sq)); ;; my @opt = ($x, $y); print add(@opt); ;; my @ra = (99, @opt, 98); print add(@ra[ 2, 1 ]); ;; exit; ;; sub add { my ($x, $y) = @_; return $x + $y; } " 5 5 5 5 5

    Questions:

    • What's the difference between feeding the strings  "$x, $y" and  '$x, $y' to eval?
    • What's  @ra[ 2, 1 ] all about? (Hint: see Slices.)

    ... dash notation ...

    This is notation used in Tcl/Tk that was, AFAIU, intentionally imported into | implemented in Perl/Tk just to make it look more familiar. Otherwise, the  => is just a "fat comma"; see perlop.


    Give a man a fish:  <%-{-{-{-<

      Thank you for the detailed answer! I see you added a couple other ways to pass arguments to subroutines; in response to your questions,
      What's the difference between feeding the strings "$x, $y" and '$x, $y' to eval?
      The first "flattens" $x and $y to their integer literal values (2, 3) and passes that to add, while the 2nd passes the variable names ($x, $y), which are then resolved to their values in add.
      What's @ra[ 2, 1 ] all about?
      Selects elements 2 and 1 - integer literals (3, 2) - from @ra and passes those to add

      If I am missing something please let me know, otherwise no need to reply. Thanks again!

        The first "flattens" $x and $y to their integer literal values (2, 3) and passes that to add ...

        I would express this somewhat differently. The word "flattens" brings to my mind the idea of "list flattening," which is not, as I see it, at work here. Instead, I would say that in the expression
            eval("$x, $y")
        the double-quote operator first interpolates the in-scope  $x $y variables into a string, and then passes the string, in this example "2, 3", a very simple source code string literal list expression, to eval to process, and indeed, eval returns just that list.

        ... the 2nd passes the variable names ($x, $y), which are then resolved to their values in add.

        Again, I would express this differently. I would say that eval is passed the "raw" string  '$x, $y' (single-quotes don't interpolate) and it is eval that resolves these variables to their values in the course of evaluating this string of Perl code, then returning the result of the evaluation. Nothing is resolved in add.

        In both cases, eval returns and add is passed exactly the same  (2, 3) list. In the second case, eval has a bit more work to do to achieve the same final result.


        Give a man a fish:  <%-{-{-{-<