Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.perl.misc > #4784 > unrolled thread

Embedding code in qq{}?

Started byXeCycle <XeCycle@Gmail.com>
First post2012-03-18 10:56 +0800
Last post2012-03-19 16:43 +0000
Articles 20 on this page of 21 — 5 participants

Back to article view | Back to comp.lang.perl.misc


Contents

  Embedding code in qq{}? XeCycle <XeCycle@Gmail.com> - 2012-03-18 10:56 +0800
    Re: Embedding code in qq{}? Uri Guttman <uri@stemsystems.com> - 2012-03-17 23:04 -0400
      Re: Embedding code in qq{}? XeCycle <XeCycle@Gmail.com> - 2012-03-18 12:14 +0800
    Re: Embedding code in qq{}? tmcd@panix.com (Tim McDaniel) - 2012-03-18 07:07 +0000
      Re: Embedding code in qq{}? Ben Morrow <ben@morrow.me.uk> - 2012-03-18 08:37 +0000
        Re: Embedding code in qq{}? tmcd@panix.com (Tim McDaniel) - 2012-03-18 22:28 +0000
          Re: Embedding code in qq{}? merlyn@stonehenge.com (Randal L. Schwartz) - 2012-03-18 16:18 -0700
            Re: Embedding code in qq{}? tmcd@panix.com (Tim McDaniel) - 2012-03-19 02:21 +0000
              Re: Embedding code in qq{}? Uri Guttman <uri@stemsystems.com> - 2012-03-19 00:14 -0400
                Re: Embedding code in qq{}? tmcd@panix.com (Tim McDaniel) - 2012-03-19 06:42 +0000
                  Re: Embedding code in qq{}? Ben Morrow <ben@morrow.me.uk> - 2012-03-19 16:40 +0000
          Re: Embedding code in qq{}? Uri Guttman <uri@stemsystems.com> - 2012-03-18 19:29 -0400
      Re: Embedding code in qq{}? Uri Guttman <uri@stemsystems.com> - 2012-03-18 15:24 -0400
        Re: Embedding code in qq{}? tmcd@panix.com (Tim McDaniel) - 2012-03-18 22:33 +0000
          Re: Embedding code in qq{}? Uri Guttman <uri@stemsystems.com> - 2012-03-18 19:24 -0400
            Re: Embedding code in qq{}? Ben Morrow <ben@morrow.me.uk> - 2012-03-19 00:49 +0000
              Re: Embedding code in qq{}? Uri Guttman <uri@stemsystems.com> - 2012-03-18 22:05 -0400
            Re: Embedding code in qq{}? tmcd@panix.com (Tim McDaniel) - 2012-03-19 02:55 +0000
              Re: Embedding code in qq{}? Uri Guttman <uri@stemsystems.com> - 2012-03-19 00:12 -0400
                Re: Embedding code in qq{}? tmcd@panix.com (Tim McDaniel) - 2012-03-19 07:00 +0000
                  Re: Embedding code in qq{}? Ben Morrow <ben@morrow.me.uk> - 2012-03-19 16:43 +0000

Page 1 of 2  [1] 2  Next page →


#4784 — Embedding code in qq{}?

FromXeCycle <XeCycle@Gmail.com>
Date2012-03-18 10:56 +0800
SubjectEmbedding code in qq{}?
Message-ID<87limyk471.fsf@Gmail.com>
Is it possible to use something like "${1+2}" -> "3"?

I use Emacs, and it's regex replace comes with a handy feature
that \,(any-lisp-form) in the replacement will be substituted
with the value of the expression.  I also want it in Perl, so I
read some manual, and found in s/regex/repl/ the repl is just
qq{repl}.  But I didn't find any notions of this feature.

-- 
Carl Lei (XeCycle)
Department of Physics, Shanghai Jiao Tong University
OpenPGP public key: 7795E591
Fingerprint: 1FB6 7F1F D45D F681 C845 27F7 8D71 8EC4 7795 E591

[toc] | [next] | [standalone]


#4785

FromUri Guttman <uri@stemsystems.com>
Date2012-03-17 23:04 -0400
Message-ID<87y5qytxrj.fsf@stemsystems.com>
In reply to#4784
>>>>> "X" == XeCycle  <XeCycle@Gmail.com> writes:

  X> Is it possible to use something like "${1+2}" -> "3"?
  X> I use Emacs, and it's regex replace comes with a handy feature
  X> that \,(any-lisp-form) in the replacement will be substituted
  X> with the value of the expression.  I also want it in Perl, so I
  X> read some manual, and found in s/regex/repl/ the repl is just
  X> qq{repl}.  But I didn't find any notions of this feature.

you are not clear in your request but my best guess is you want an
expression in the replacement part of s///. calling that a qq{} is
somewhat misleading as they do have slightly different features. but the
/e option to s/// is what you want. then the replacement is a full
expression and not a string. this is documented in perlop for s///.

uri

[toc] | [prev] | [next] | [standalone]


#4786

FromXeCycle <XeCycle@Gmail.com>
Date2012-03-18 12:14 +0800
Message-ID<87haxmk0kl.fsf@Gmail.com>
In reply to#4785
Uri Guttman <uri@stemsystems.com> writes:

[...]

> you are not clear in your request but my best guess is you want an
> expression in the replacement part of s///. calling that a qq{} is
> somewhat misleading as they do have slightly different features. but the
> /e option to s/// is what you want. then the replacement is a full
> expression and not a string. this is documented in perlop for s///.
>
> uri

Wow, thanks for that.  I read somewhere that the replacement is
simply qq{}, didn't realize this.

-- 
Carl Lei (XeCycle)
Department of Physics, Shanghai Jiao Tong University
OpenPGP public key: 7795E591
Fingerprint: 1FB6 7F1F D45D F681 C845 27F7 8D71 8EC4 7795 E591

[toc] | [prev] | [next] | [standalone]


#4787

Fromtmcd@panix.com (Tim McDaniel)
Date2012-03-18 07:07 +0000
Message-ID<jk41js$p48$1@reader1.panix.com>
In reply to#4784
In article <87limyk471.fsf@Gmail.com>, XeCycle  <XeCycle@Gmail.com>
wrote:
>Is it possible to use something like "${1+2}" -> "3"?

You made it clear in the rest of the article (which I trimmed) that
you were thinking about the right-hand side of a s///.  It turns out
that, in string contexts in general, you can do it.

Short answer:
    ${\(1+2)}

There are a couple of replies in
http://stackoverflow.com/questions/2332815/why-does-perl-evaluate-code-in-during-string-interpolation
that explain it.  I'll try to distill it.

There's a crucial sentence in "man perlref":

    Anywhere you'd put an identifier (or chain of identifiers) as part
    of a variable or subroutine name, you can replace the identifier
    with a BLOCK returning a reference of the correct type.

What does that mean?  Consider a simple scalar variable
    $foo
The identifier is "foo", so you can replace it with a block:
    ${ almost arbitrary code that evaluates to a ref to a scalar}
The only constraint is that the code has to evaluate to a reference to
a scalar.  Similarly for the array sigil
    @{ almost arbitrary code that evaluates to a ref to an array}
And I presume % and & too, though I didn't try them.

And I believe any of those can also appear in a double-quoted string.

Here's my example program (it happens to be my eighty-seventh test
script).  The stuff commented out with "##" causes the syntax errors
noted after them.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#! /usr/bin/perl
use strict;
use warnings;

my $x = 'hello';
my $y = 'world';
print "${ \$x }\n";
print "${ if (0) { \$x; } else { \$y }; }\n";
## print "hey@{1+2}there\n"; # Can't use string ("3") as an ARRAY ref while "strict refs" in use at local/test/087.pl line 9.
print "hey${\(1+2)}there\n";
$" = '<blort>';
print "hey@{[1+2, 3*4]}there\n";
## print "hey${ { \$x; last; }; \$y }there\n";
# syntax error at local/test/087.pl line 13, near "; last"
# syntax error at local/test/087.pl line 13, near "};"
# Execution of local/test/087.pl aborted due to compilation errors.
print "hey${ ; { \$x; last; }; \$y }there\n"; # Useless use of single ref constructor in void context at local/test/087.pl line 17.
print ${ \$x }, "\n";
exit 0;

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The output is

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Useless use of single ref constructor in void context at
local/test/087.pl line 17.
hello
world
hey3there
hey3<blort>12there
heyworldthere
hello

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If the block evaluates to a string, then it's looked up as the name of
a dynamic variable (as in "our", not "my").  I believe that's what
it's erroring about when line 9 is uncommented.

Note that the block parsing is not quite right (in Perl 5.10),
apparently when confronted with leading "{ {", as in
    ${ { \$x; last; }; \$y }
above.  As shown above, putting in a null statement at the start
unconfuses it.

It's a "block" in the same way as do { ... } instead of { ... }: it
doesn't allow "last" (though you can throw in interior {...} to make
it work, as shown in the example), and "return" returns from an
enclosing sub rather than the block.

So, back to your original question, see
    print "hey${\(1+2)}there\n";
above, which outputs
    hey3there

-- 
Tim McDaniel, tmcd@panix.com

[toc] | [prev] | [next] | [standalone]


#4788

FromBen Morrow <ben@morrow.me.uk>
Date2012-03-18 08:37 +0000
Message-ID<1fjg39-qnv2.ln1@anubis.morrow.me.uk>
In reply to#4787
Quoth tmcd@panix.com:
> In article <87limyk471.fsf@Gmail.com>, XeCycle  <XeCycle@Gmail.com>
> wrote:
> >Is it possible to use something like "${1+2}" -> "3"?
> 
> You made it clear in the rest of the article (which I trimmed) that
> you were thinking about the right-hand side of a s///.  It turns out
> that, in string contexts in general, you can do it.
> 
> Short answer:
>     ${\(1+2)}

If you must do this, then @{[...]} is clearer, since in both cases the
internal code is evaluated in list context.

In practice it's nearly always clearer to use sprintf.

> What does that mean?  Consider a simple scalar variable
>     $foo
> The identifier is "foo", so you can replace it with a block:
>     ${ almost arbitrary code that evaluates to a ref to a scalar}
> The only constraint is that the code has to evaluate to a reference to
> a scalar.  Similarly for the array sigil
>     @{ almost arbitrary code that evaluates to a ref to an array}
> And I presume % and & too, though I didn't try them.

Yes. And *{...}.

> And I believe any of those can also appear in a double-quoted string.

Neither %{...} nor &{...} will interpolate into a double-quoted string
anyway, so you can't use them to interpolate expressions either.

Ben

[toc] | [prev] | [next] | [standalone]


#4794

Fromtmcd@panix.com (Tim McDaniel)
Date2012-03-18 22:28 +0000
Message-ID<jk5nht$ot8$1@reader1.panix.com>
In reply to#4788
In article <1fjg39-qnv2.ln1@anubis.morrow.me.uk>,
Ben Morrow  <ben@morrow.me.uk> wrote:
>
>Quoth tmcd@panix.com:
>> In article <87limyk471.fsf@Gmail.com>, XeCycle  <XeCycle@Gmail.com>
>> wrote:
>> >Is it possible to use something like "${1+2}" -> "3"?
>> 
>> You made it clear in the rest of the article (which I trimmed) that
>> you were thinking about the right-hand side of a s///.  It turns out
>> that, in string contexts in general, you can do it.
>> 
>> Short answer:
>>     ${\(1+2)}
>
>If you must do this, then @{[...]} is clearer, since in both cases
>the internal code is evaluated in list context.

Both are in a scalar context, I think.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#! /usr/bin/perl
use strict;
use warnings;

sub tester {
    if (wantarray) {
        print "array context\n";
        return [ 11, 12, 13 ];
    } else {
        print "scalar context\n";
        return \(22);
    }
}

print "scalar: ", ${tester()}, "\n";
print "array: ", @{tester()}, "\n";
exit 0;

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Output:

$ perl local/test/088.pl
scalar context
scalar: 22
scalar context
Not an ARRAY reference at local/test/088.pl line 16.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In retrospect, that makes sense.  The ${...} and @{...} sigils want
the block to return *one reference*, which is a scalar, so why not
evaluate in scalar context?

The advantage I see for @{[BODY]} even for a scalar is that you just
need to have BODY evaluate to a normal scalar. [...] takes care of
changing it to the required reference, and @{...} converts it to an
array of one element, which within a string and a list context
evaluates to the original scalar (though of course you have to be
careful in a scalar context not to blindly use it and get the length,
1).

However, ${BODY} has to have the BODY evaluate to a reference to a
scalar, which may make \ have to spring up throughout.

-- 
Tim McDaniel, tmcd@panix.com

[toc] | [prev] | [next] | [standalone]


#4796

Frommerlyn@stonehenge.com (Randal L. Schwartz)
Date2012-03-18 16:18 -0700
Message-ID<86fwd5wl9d.fsf@red.stonehenge.com>
In reply to#4794
>>>>> "Tim" == Tim McDaniel <tmcd@panix.com> writes:

Tim> print "scalar: ", ${tester()}, "\n";

I'm amazed this works. :)

Tim> print "array: ", @{tester()}, "\n";

You forgot the square brackets.

-- 
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc.
See http://methodsandmessages.posterous.com/ for Smalltalk discussion

[toc] | [prev] | [next] | [standalone]


#4801

Fromtmcd@panix.com (Tim McDaniel)
Date2012-03-19 02:21 +0000
Message-ID<jk657m$383$1@reader1.panix.com>
In reply to#4796
In article <86fwd5wl9d.fsf@red.stonehenge.com>,
Randal L. Schwartz <merlyn@stonehenge.com> wrote:
>>>>>> "Tim" == Tim McDaniel <tmcd@panix.com> writes:
>
>Tim> print "scalar: ", ${tester()}, "\n";
>
>I'm amazed this works.

Why?  The basic syntax for a scalar variable is $identifier, and man
perlref (Perl 5.10):

"Anywhere you'd put an identifier (or chain of identifiers) as part of
a variable or subroutine name, you can replace the identifier with a
BLOCK returning a reference of the correct type."

So replace "identifier" with a BLOCK.  The BLOCK is
    {tester()}
That sub returns the required reference to a scalar.  It's no more
surprising than
    ${\(22)}
which is what it returns.

>Tim> print "array: ", @{tester()}, "\n";
>
>You forgot the square brackets.

No, I didn't.  They are not required -- just a BLOCK that returns a
reference to an array.  Of course, square brackets are a convenient
way to generate such a reference.  Had tester been called in an array
context (which, as I noted, in retrospect would make no sense), it
would have returned [ 11, 12, 13 ].

I just ran this in Perl 5.10:

#! /usr/bin/perl
use strict;
use warnings;
sub poit { return [ 11, 22, 33]; }
sub pondering { my @a = (44, 55, 66); return \@a; }
print join(' narf ', @{poit();}), "\n";
print join(' zort ', @{pondering();}), "\n";
exit 0;

Output:
$ perl local/test/090.pl
11 narf 22 narf 33
44 zort 55 zort 66

In the "pondering" case, nary a square bracket in sight.

-- 
Tim McDaniel, tmcd@panix.com

[toc] | [prev] | [next] | [standalone]


#4804

FromUri Guttman <uri@stemsystems.com>
Date2012-03-19 00:14 -0400
Message-ID<878vixtef8.fsf@stemsystems.com>
In reply to#4801
>>>>> "TM" == Tim McDaniel <tmcd@panix.com> writes:

  TM> In article <86fwd5wl9d.fsf@red.stonehenge.com>,
  TM> Randal L. Schwartz <merlyn@stonehenge.com> wrote:
  >>>>>>> "Tim" == Tim McDaniel <tmcd@panix.com> writes:
  >> 
  Tim> print "scalar: ", ${tester()}, "\n";
  >> 
  >> I'm amazed this works.

  TM> Why?  The basic syntax for a scalar variable is $identifier, and man
  TM> perlref (Perl 5.10):

please put your sarcasm detector on high gain. do you realize who you
replied to?

  Tim> print "array: ", @{tester()}, "\n";
  >> 
  >> You forgot the square brackets.

  TM> No, I didn't.  They are not required -- just a BLOCK that returns a
  TM> reference to an array.  Of course, square brackets are a convenient
  TM> way to generate such a reference.  Had tester been called in an array
  TM> context (which, as I noted, in retrospect would make no sense), it
  TM> would have returned [ 11, 12, 13 ].

without the [] it isn't close to the idiom being discussed. and as i
mentioned it wasn't in "" so it really bypasses the idiom. a plain deref
is just a plain deref, nothing to jump up and down about.

  TM> I just ran this in Perl 5.10:

  TM> In the "pondering" case, nary a square bracket in sight.

you are wandering in the wilderness. please go home! :)

uri

[toc] | [prev] | [next] | [standalone]


#4805

Fromtmcd@panix.com (Tim McDaniel)
Date2012-03-19 06:42 +0000
Message-ID<jk6kg1$l5k$1@reader1.panix.com>
In reply to#4804
In article <878vixtef8.fsf@stemsystems.com>,
Uri Guttman  <uri@stemsystems.com> wrote:
>>>>>> "TM" == Tim McDaniel <tmcd@panix.com> writes:
>
>  TM> In article <86fwd5wl9d.fsf@red.stonehenge.com>,
>  TM> Randal L. Schwartz <merlyn@stonehenge.com> wrote:
>  >>>>>>> "Tim" == Tim McDaniel <tmcd@panix.com> writes:
>  >> 
>  Tim> print "scalar: ", ${tester()}, "\n";
>  >> 
>  >> I'm amazed this works.
>
>  TM> Why?  The basic syntax for a scalar variable is $identifier,
>  TM> and man perlref (Perl 5.10):
>
>please put your sarcasm detector on high gain. do you realize who you
>replied to?

Of course I realize.  Given the man page quotations that I've posted
that some people have ignored, and the test programs and output that
I've posted that some people have ignored, it wouldn't surprise me at
all if even Randal were to join that pack.

>  Tim> print "array: ", @{tester()}, "\n";
>  >> 
>  >> You forgot the square brackets.
>
>  TM> No, I didn't.
>
>without the [] it isn't close to the idiom being discussed.

I'm not discussing the idiom per se, but the general case that
explains it and much else.

>and as i mentioned it wasn't in "" so it really bypasses the idiom.

The behavior in "..." is a simple consequence of interpolating a
scalar or array in a string.

>you are wandering in the wilderness. please go home!

I'm sorry that I yet fail see by what authority you order me out of
the newsgroup.  But if you post it, I'll be sure to follow the fashion
by ignoring it, misreading it, and shifting the goalposts.

-- 
Tim McDaniel, tmcd@panix.com

[toc] | [prev] | [next] | [standalone]


#4810

FromBen Morrow <ben@morrow.me.uk>
Date2012-03-19 16:40 +0000
Message-ID<t44k39-51o.ln1@anubis.morrow.me.uk>
In reply to#4805
Quoth tmcd@panix.com:
> 
> I'm sorry that I yet fail see by what authority you order me out of
> the newsgroup.  But if you post it, I'll be sure to follow the fashion
> by ignoring it, misreading it, and shifting the goalposts.

Careful. Insulting long-time regulars, even if you think they're clearly
in the wrong, is a sure way to end up in lots of killfiles.

Ben

[toc] | [prev] | [next] | [standalone]


#4798

FromUri Guttman <uri@stemsystems.com>
Date2012-03-18 19:29 -0400
Message-ID<87limxtrn6.fsf@stemsystems.com>
In reply to#4794
>>>>> "TM" == Tim McDaniel <tmcd@panix.com> writes:

  TM> In article <1fjg39-qnv2.ln1@anubis.morrow.me.uk>,
  TM> Ben Morrow  <ben@morrow.me.uk> wrote:
  >> 
  >> Quoth tmcd@panix.com:
  >>> In article <87limyk471.fsf@Gmail.com>, XeCycle  <XeCycle@Gmail.com>
  >>> wrote:
  >>> >Is it possible to use something like "${1+2}" -> "3"?
  >>> 
  >>> You made it clear in the rest of the article (which I trimmed) that
  >>> you were thinking about the right-hand side of a s///.  It turns out
  >>> that, in string contexts in general, you can do it.
  >>> 
  >>> Short answer:
  >>> ${\(1+2)}
  >> 
  >> If you must do this, then @{[...]} is clearer, since in both cases
  >> the internal code is evaluated in list context.

  TM> Both are in a scalar context, I think.

i know that to be wrong. one classic issue was that ${\bar()} always
calls in list context. there is no implicit way to get scalar context
there.
>>>>> "TM" == Tim McDaniel <tmcd@panix.com> writes:

  TM> In article <1fjg39-qnv2.ln1@anubis.morrow.me.uk>,
  TM> Ben Morrow  <ben@morrow.me.uk> wrote:
  >> 
  >> Quoth tmcd@panix.com:
  >>> In article <87limyk471.fsf@Gmail.com>, XeCycle  <XeCycle@Gmail.com>
  >>> wrote:
  >>> >Is it possible to use something like "${1+2}" -> "3"?
  >>> 
  >>> You made it clear in the rest of the article (which I trimmed) that
  >>> you were thinking about the right-hand side of a s///.  It turns out
  >>> that, in string contexts in general, you can do it.
  >>> 
  >>> Short answer:
  >>> ${\(1+2)}
  >> 
  >> If you must do this, then @{[...]} is clearer, since in both cases
  >> the internal code is evaluated in list context.

  TM> Both are in a scalar context, I think.

  TM> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  TM> #! /usr/bin/perl
  TM> use strict;
  TM> use warnings;

  TM> sub tester {
  TM>     if (wantarray) {
  TM>         print "array context\n";
  TM>         return [ 11, 12, 13 ];
  TM>     } else {
  TM>         print "scalar context\n";
  TM>         return \(22);
  TM>     }
  TM> }

  TM> print "scalar: ", ${tester()}, "\n";
  TM> print "array: ", @{tester()}, "\n";

those are not correct tests. neither is being interpolated into a string
nor is \ being used. just a dereference in code will of course provide a
scalar context as you need a single scalar value to dereference.

change the code to "scalar: ${\tester()}\n" and "array: ${[tester()]}\n"
and see what happens. that is looking at the context in interpolation.

uri

[toc] | [prev] | [next] | [standalone]


#4792

FromUri Guttman <uri@stemsystems.com>
Date2012-03-18 15:24 -0400
Message-ID<87ty1lu2z7.fsf@stemsystems.com>
In reply to#4787
>>>>> "TM" == Tim McDaniel <tmcd@panix.com> writes:

  TM> In article <87limyk471.fsf@Gmail.com>, XeCycle  <XeCycle@Gmail.com>
  TM> wrote:
  >> Is it possible to use something like "${1+2}" -> "3"?

  TM> You made it clear in the rest of the article (which I trimmed) that
  TM> you were thinking about the right-hand side of a s///.  It turns out
  TM> that, in string contexts in general, you can do it.

  TM> Short answer:
  TM>     ${\(1+2)}

bad answer. first off it isn't needed as the /e modifier to s/// does
it. secondly it is a bad idea in general. the syntax for that is clunky
and hard to read. yes, it is legal and works. i just never do it nor
teach it to anyone. it is just poor coding IMNSHO.

uri

[toc] | [prev] | [next] | [standalone]


#4795

Fromtmcd@panix.com (Tim McDaniel)
Date2012-03-18 22:33 +0000
Message-ID<jk5nsj$ot8$2@reader1.panix.com>
In reply to#4792
In article <87ty1lu2z7.fsf@stemsystems.com>,
Uri Guttman  <uri@stemsystems.com> wrote:
>>>>>> "TM" == Tim McDaniel <tmcd@panix.com> writes:
>
>  TM> In article <87limyk471.fsf@Gmail.com>, XeCycle  <XeCycle@Gmail.com>
>  TM> wrote:
>  >> Is it possible to use something like "${1+2}" -> "3"?
>
>  TM> You made it clear in the rest of the article (which I trimmed)
>  TM> that you were thinking about the right-hand side of a s///.  It
>  TM> turns out that, in string contexts in general, you can do it.
>
>  TM> Short answer:
>  TM>     ${\(1+2)}
>
>bad answer.  first off it isn't needed as the /e modifier to s/// does
>it.

Which I tried to make clear but didn't.  I wasn't trying to address
the s/// case; everyone who pointed out s///e covered it quite nicely.
I was trying to cover the case of being outside the RHS of s///.

>secondly it is a bad idea in general. the syntax for that is clunky
>and hard to read. yes, it is legal and works. i just never do it nor
>teach it to anyone. it is just poor coding IMNSHO.

I see one use for it: @{[...]} interpolates a sub call into a quoted
string, which you could not otherwise interpolate in a string.  Since
"use constant" makes the constant be a sub, that's also how you
interpolate a "use constant" constant.  (My work systems have Perl
5.8, and I have no control over the Perl version or the Perl stock of
libraries, so I have to pretty much stick to stock Perl 5.8.)

It does help clarify for me what ${...} means, that ... is simply a
block that returns a value.

-- 
Tim McDaniel, tmcd@panix.com

[toc] | [prev] | [next] | [standalone]


#4797

FromUri Guttman <uri@stemsystems.com>
Date2012-03-18 19:24 -0400
Message-ID<87pqc9trvt.fsf@stemsystems.com>
In reply to#4795
>>>>> "TM" == Tim McDaniel <tmcd@panix.com> writes:

  TM> In article <87ty1lu2z7.fsf@stemsystems.com>,
  TM> Uri Guttman  <uri@stemsystems.com> wrote:
  >>>>>>> "TM" == Tim McDaniel <tmcd@panix.com> writes:
  >> 
  TM> In article <87limyk471.fsf@Gmail.com>, XeCycle  <XeCycle@Gmail.com>
  TM> wrote:
  >> >> Is it possible to use something like "${1+2}" -> "3"?
  >> 
  TM> You made it clear in the rest of the article (which I trimmed)
  TM> that you were thinking about the right-hand side of a s///.  It
  TM> turns out that, in string contexts in general, you can do it.
  >> 
  TM> Short answer:
  TM> ${\(1+2)}
  >> 
  >> bad answer.  first off it isn't needed as the /e modifier to s/// does
  >> it.

  TM> Which I tried to make clear but didn't.  I wasn't trying to address
  TM> the s/// case; everyone who pointed out s///e covered it quite nicely.
  TM> I was trying to cover the case of being outside the RHS of s///.

but the OP was only really asking about s///. he conflated the
replacement part with a "" and was wrong there.

  >> secondly it is a bad idea in general. the syntax for that is clunky
  >> and hard to read. yes, it is legal and works. i just never do it nor
  >> teach it to anyone. it is just poor coding IMNSHO.

  TM> I see one use for it: @{[...]} interpolates a sub call into a quoted
  TM> string, which you could not otherwise interpolate in a string.  Since
  TM> "use constant" makes the constant be a sub, that's also how you
  TM> interpolate a "use constant" constant.  (My work systems have Perl
  TM> 5.8, and I have no control over the Perl version or the Perl stock of
  TM> libraries, so I have to pretty much stick to stock Perl 5.8.)

it still is a poor construct to use. there is an Interpolate module that
does this with better syntax $() iirc. perl6 properly supports this idea
as well.

  TM> It does help clarify for me what ${...} means, that ... is simply a
  TM> block that returns a value.

${foo} is not such a thing. so your clarification is not totally
correct. the more i think about it, it isn't a true block in general. it is a
dereference operation that allows statements. you can't last out of it
(which you can from a bare block). so it is a limited type of block and
meant only for dereferencing. it will blow up if the last value is not
the proper ref type. a regular block need not return any value or if it
does (a do block, map block), it can return anything. there are some
serious differences so i wouldn't call it just a block.

uri

[toc] | [prev] | [next] | [standalone]


#4799

FromBen Morrow <ben@morrow.me.uk>
Date2012-03-19 00:49 +0000
Message-ID<9eci39-1da.ln1@anubis.morrow.me.uk>
In reply to#4797
Quoth Uri Guttman <uri@stemsystems.com>:
> 
> it still is a poor construct to use. there is an Interpolate module that
> does this with better syntax $() iirc. perl6 properly supports this idea
> as well.

Oddly there doesn't seem to be, at least not on CPAN. In any case, it
looks like this:
    
    package Interpolate;

    use Exporter "import";
    our @EXPORT = '%I';

    sub TIEHASH { bless \my $x }
    sub FETCH   { $_[1]        }

    tie our %I, __PACKAGE__;

    1;

and you use it like this
    
    sub ctx { wantarray ? "LIST" : defined wantarray ? "SCALAR" : "VOID" }

    say "context: $I{ctx()}";

I wonder if it only ever existed as an example in the Camel book?

(Annoyingly the obvious trick of tying %$ and %@ so you can use 
"$${ foo() }" and "@@{ foo() }" doesn't work, since they parse as
derefs. Tying %_ does work, but that's probably too many uses for '_'.
Perhaps %:?)

Ben

[toc] | [prev] | [next] | [standalone]


#4800

FromUri Guttman <uri@stemsystems.com>
Date2012-03-18 22:05 -0400
Message-ID<87haxltken.fsf@stemsystems.com>
In reply to#4799
>>>>> "BM" == Ben Morrow <ben@morrow.me.uk> writes:

  BM> Quoth Uri Guttman <uri@stemsystems.com>:
  >> 
  >> it still is a poor construct to use. there is an Interpolate module that
  >> does this with better syntax $() iirc. perl6 properly supports this idea
  >> as well.

  BM> Oddly there doesn't seem to be, at least not on CPAN. In any case, it
  BM> looks like this:

http://search.cpan.org/~mjd/Interpolation-0.53/Interpolation.pm

wrong name from my memory. this does all sorts of stuff like that.

uri

[toc] | [prev] | [next] | [standalone]


#4802

Fromtmcd@panix.com (Tim McDaniel)
Date2012-03-19 02:55 +0000
Message-ID<jk677e$9vk$1@reader1.panix.com>
In reply to#4797
In article <87pqc9trvt.fsf@stemsystems.com>,
Uri Guttman  <uri@stemsystems.com> wrote:
>>>>>> "TM" == Tim McDaniel <tmcd@panix.com> writes:
>
>  TM> In article <87ty1lu2z7.fsf@stemsystems.com>,
>  TM> Uri Guttman  <uri@stemsystems.com> wrote:
>  >> bad answer.  first off it isn't needed as the /e modifier to
>  >> s/// does it.
>
>  TM> Which I tried to make clear but didn't.  I wasn't trying to
>  TM> address the s/// case; everyone who pointed out s///e covered
>  TM> it quite nicely.  I was trying to cover the case of being
>  TM> outside the RHS of s///.
>
>but the OP was only really asking about s///.

I'm not allowed to bring up new stuff?  I'm only allowed to address
the one case that someone asks about and not tangent off onto
something else?

And in any event, it works on the right-hand side of s///:

#! /usr/bin/perl
use strict;
use warnings;
$_ = 'abcde';
s/c/ before ${my $q = 23; \(9+$q)} after /;
print "$_\n";
exit 0;

Output:

$ perl local/test/092.pl
ab before 32 after de

>  TM> It does help clarify for me what ${...} means, that ... is
>  TM> simply a block that returns a value.
>
>${foo} is not such a thing.

To repeat again, man perlref says it is.

    Anywhere you'd put an identifier (or chain of identifiers) as part
    of a variable or subroutine name, you can replace the identifier
    with a BLOCK returning a reference of the correct type.

>the more i think about it, it isn't a true block in general. it is a
>dereference operation that allows statements. you can't last out of
>it

"Being able to last out of it" is not Perl's definition of block.
man perlsyn says

    In Perl, a sequence of statements that defines a scope is called a
    block.  Sometimes a block is delimited by the file containing it
    (in the case of a required file, or the program as a whole), and
    sometimes a block is delimited by the extent of a string (in the
    case of an eval).

    But generally, a block is delimited by curly brackets, also known
    as braces.  We will call this syntactic construct a BLOCK.

As I explained before, it's a block just the same as do {...}.
You can't last out of do{...} either, or map or grep, but
perlfunc still explains the syntax as
    do BLOCK
    map BLOCK LIST
    grep BLOCK LIST
or, for that matter,
    if (EXPR) BLOCK
    if (EXPR) BLOCK else BLOCK
    if (EXPR) BLOCK elsif (EXPR) BLOCK ... else BLOCK
    sub [NAME] BLOCK
or even the source file itself.  There are all sorts of blocks you
can't last or next in.  Are you saying that the body of a sub isn't a
block?

>(which you can from a bare block).

"last" is specifically a *loop* control structure, and a bare block,
as the perlfunc do docs says

    "do BLOCK" does not count as a loop, so the loop control
    statements "next", "last", or "redo" cannot be used to leave or
    restart the block.  See perlsyn for alternative strategies.

man perlsyn explains:

    A BLOCK by itself (labeled or not) is semantically equivalent to a
    loop that executes once.  Thus you can use any of the loop control
    statements in it to leave or restart the block.  (Note that this
    is NOT true in "eval{}", "sub{}", or contrary to popular belief
    "do{}" blocks, which do NOT count as loops.)  The "continue" block
    is optional.

As for it being limited, as you note and I snipped: There are all
sorts of limitations in various contexts.  The value of a sub is
limited too, if it returns something the caller will die on in
context.

As for it being useful: a general block in $BLOCK or @BLOCK is not in
practice useful, readable, helpful, or whatever.  Still, that's how
it's explained in the documentation.

-- 
Tim McDaniel, tmcd@panix.com

[toc] | [prev] | [next] | [standalone]


#4803

FromUri Guttman <uri@stemsystems.com>
Date2012-03-19 00:12 -0400
Message-ID<87d389tej9.fsf@stemsystems.com>
In reply to#4802
>>>>> "TM" == Tim McDaniel <tmcd@panix.com> writes:

  TM> In article <87pqc9trvt.fsf@stemsystems.com>,
  TM> Uri Guttman  <uri@stemsystems.com> wrote:
  >>>>>>> "TM" == Tim McDaniel <tmcd@panix.com> writes:
  >> 
  TM> In article <87ty1lu2z7.fsf@stemsystems.com>,
  TM> Uri Guttman  <uri@stemsystems.com> wrote:
  >> >> bad answer.  first off it isn't needed as the /e modifier to
  >> >> s/// does it.
  >> 
  TM> Which I tried to make clear but didn't.  I wasn't trying to
  TM> address the s/// case; everyone who pointed out s///e covered
  TM> it quite nicely.  I was trying to cover the case of being
  TM> outside the RHS of s///.
  >> 
  >> but the OP was only really asking about s///.

  TM> I'm not allowed to bring up new stuff?  I'm only allowed to address
  TM> the one case that someone asks about and not tangent off onto
  TM> something else?

you can but it wasn't clear (as you said) that it was additional
stuff. and it wasn't the best stuff IMO either. 

  TM> And in any event, it works on the right-hand side of s///:

who ever said it wouldn't work there? the replacement side is a ""
string with some slight differences. but /e is better anyhow.

  TM> To repeat again, man perlref says it is.

  TM>     Anywhere you'd put an identifier (or chain of identifiers) as part
  TM>     of a variable or subroutine name, you can replace the identifier
  TM>     with a BLOCK returning a reference of the correct type.

  >> the more i think about it, it isn't a true block in general. it is a
  >> dereference operation that allows statements. you can't last out of
  >> it

  TM> "Being able to last out of it" is not Perl's definition of block.
  TM> man perlsyn says

  TM>     In Perl, a sequence of statements that defines a scope is called a
  TM>     block.  Sometimes a block is delimited by the file containing it
  TM>     (in the case of a required file, or the program as a whole), and
  TM>     sometimes a block is delimited by the extent of a string (in the
  TM>     case of an eval).

  TM>     But generally, a block is delimited by curly brackets, also known
  TM>     as braces.  We will call this syntactic construct a BLOCK.

and in most brace blocks you can last out. you can't in a dereference
block. hence it isn't the same as the others. you can't do various
things in the various types of blocks. it is good to know the difference
vs thinking they are all the same blocks. 

  >> (which you can from a bare block).

  TM> "last" is specifically a *loop* control structure, and a bare block,
  TM> as the perlfunc do docs says

  TM>     "do BLOCK" does not count as a loop, so the loop control
  TM>     statements "next", "last", or "redo" cannot be used to leave or
  TM>     restart the block.  See perlsyn for alternative strategies.

  TM> man perlsyn explains:

  TM>     A BLOCK by itself (labeled or not) is semantically equivalent to a
  TM>     loop that executes once.  Thus you can use any of the loop control
  TM>     statements in it to leave or restart the block.  (Note that this
  TM>     is NOT true in "eval{}", "sub{}", or contrary to popular belief
  TM>     "do{}" blocks, which do NOT count as loops.)  The "continue" block
  TM>     is optional.

and it doesn't say the ${} block is either case. 

uri

[toc] | [prev] | [next] | [standalone]


#4806

Fromtmcd@panix.com (Tim McDaniel)
Date2012-03-19 07:00 +0000
Message-ID<jk6lic$1h3$1@reader1.panix.com>
In reply to#4803
I come to despise long chains of replies with several levels of
quoting all going over the same points, or people shifting goalposts
or going on into more false things.

I believe that I have adequately demonstrated, by quotations from man
pages and from test programs,
- $BLOCK, @BLOCK, and the rest take a BLOCK as defined by Perl,
  so long as the BLOCK finishes with a reference of the type demanded
  by the sigil
- they may be used as values in expressions whever a similar variable
  might be used
- someone else pointed out that only $BLOCK and @BLOCK may be
  interpolated into strings -- thank you for that.  (I'm sorry I've
  forgotten who, and I can't check while composing an article).  I
  assume the same is true for the right-hand side of s///
- I think it's not a particularly good idea except in certain simple
  cases -- removing the BLOCK and assigning a variable before would
  usually be clearer

I don't see much point in going on, unless someone posts something
new and false.

-- 
Tim McDaniel, tmcd@panix.com

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.perl.misc


csiph-web