Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?

Can perl do...?

by nashdj (Friar)
on Jun 04, 2000 at 11:51 UTC ( #16275=perlquestion: print w/replies, xml ) Need Help??

nashdj has asked for the wisdom of the Perl Monks concerning the following question:

I was sitting around with nothign to do today. So I figured I would just play around with perl, and play around I did.

But I came across a few things, that I'm not sure if you can do. Well, sure there are other ways of doing the same, but the way I wanted to do some things, seemed to make a lot of sense and was simpler.

Firstly, $foo = ("this $foo" =~ s/a/b/); Well that obviously wont work because for one thing it is trying to modify a static string, and secondly because what we are actually placing into $foo at the end is the number of substitutions.
But why cant we modify a static string, sure it is "static" but if during execution perl creates a (non existant) variable to store it in. Do I make any sense, probably not. :)
The second step, assigning the actual result back to $foo, is there a way to do that (no I mean, is there a perlvar to set which causes it to do what I want)?

Next, I often find myself assigning a value to $_. Simple to do "$_ = $foo;" but I see that too much. What I was thinking would be nice was simply... $foo; Which by itself seems to serve no purpose, other than being usefull in a sub as a return. Again, am I missing something, is there a shorthand "$_ =" already?

Ok and for my last wish :) (no no, two actually)
Occasionally I find myself in a for (well foreach rather) loop, and want to find the previous value of $_
for(@_) { $in .=' '.($t = $_ - $last); $last = $_; }
Which can be done like that, but.. What I had in mind, was treating $_ as a stack. Each time it takes on a new value the stack is pushed up. The previous value could be given the name $__ then $___ and so on, but that could get very messy :) (does perl have something similar already?)...
Finally, as you see above I was using a for(@_) loop. Pretty short to do, but again... :) Does a standalone "for" do anything? I thought it would be nice if for{} == for(@_){}.

So there you have it, am I crazy, is all this already here. If not are there reasons why, or do you think they should be.

Replies are listed 'Best First'.
Re: Can perl do...?
by athomason (Curate) on Jun 04, 2000 at 13:39 UTC

    1) Like you say, the substitution operator doesn't do what you want; it's only for real variables. This is because it is an operator that needs an lvalue to modify. You can't use s/// with static strings for the same reason you can't do "'x'++;" or "'x'=3;". If you don't want to create a new variable, the fastest way is to assign your static or interpolated string to $_ and then use the substitution operator; then you can even drop the binding operator =~.

    2) Sorry, you have to type the five extra characters "$_ = " :-P. The insanity resulting from putting the result of every statement into $_ would far outweigh the small convenience. You'd always have to be on the lookout for what blew away $_ (even more so than now); I suspect it would make the variable much less useful. Also, explicitly putting in the assignment makes the code significantly clearer; even if you could take it out, you probably shouldn't.

    3)This is what numerical indices are for. Sorry, but you can't throw out all your C habits ;-). Just have an integer variable (say, $i) and then when you need to reference the previous value use $_[$i-1]. For (which is a synonym for foreach) does require at least one parameter; if you want an infinite loop use for(;;){...};. On another note, @_ doesn't have the same "temporary" role that $_ does. @_ is for passing arguments to subs, so once again it's much more clear and barely more difficult to just type it. On an even less related note, while loops DO have funky semantics when you use "<>" as the sole argument. Namely, it will take elements from @ARGV, assume they are filenames, get data from those files, then read from STDIN.

    Update: foobah's comments below are all correct; I fixed the first but check the others for clarifications.

      Don't know if I could have asked for a better answer. Everything seems so clear the way you have explained it.
      Just a few notes; instead of @_$[i-1] I think you meant $_[$i - 1] Also, although it's deprecated, split in void context splits into @_, so @_ can sometimes have a "temporary" role. Lastly, while (<>) { ... } doesn't assume that @ARGV contains only filenames; @ARGV may also contain pipe commands.
      There is still one thing beyond me. What about.. $foo; What purpose does it serve being able to do that. As I said before all I can think it would be good for is as a return for a sub. (I really need to get some books dont I)
      I'm just curious :)
        That doesn't do anything at all; you're introducing a value into a null context. That is, your statement has no effect whatsoever since there are no side effects. For instance, try the one-liner perl -we "$_;"Using the -w flag will let you know when your statements aren't doing anything.
Re: Can perl do...?
by sean (Beadle) on Jun 04, 2000 at 19:08 UTC
    For that first part there: $foo = ("this $foo" =~ s/a/b/); If you shuffle the parens around thusly: ($foo = "this $foo") =~ s/a/b/; It would do what you want. --sean
      Brilliant! I just need to think sideways more than I am I guess :)
Re: Can perl do...?
by takshaka (Friar) on Jun 05, 2000 at 01:39 UTC
    ($foo = "this $foo") =~ s/a/b/; This is a perfectly legitimate expression, which seems to be what nashdj wants to do.

    From perlop:
    The string specified with =~ must be scalar variable, an array element, a hash element, or an assignment to one of those, i.e., an lvalue.
    my %japh = qw(J Just A Another P Perl H Hacker); ($_ = 'J A P H') =~ s/(\w)/$japh{$1}/g; print;
    Hmm...I swear sean's reply wasn't there a moment ago. Darn temporal displacement again. Anyway, he's right and so am I. Vote for his.
Re: Can perl do...?
by Aighearach (Initiate) on Jun 04, 2000 at 13:47 UTC

    > But why cant we modify a static string, sure it is "static" but if during execution perl creates a (non existant) variable to store it in.

    You could try something like:

    use strict; my $foo = "bar"; my $test = sub { my $string = "$foo out"; $string =~ s/b/f/; return $s +tring }; print &$test,"\n";

    It's not really what you were asking for, but it lets you modify a string, and still have it seem static afterwards.

    Paris Sinclair    |    4a75737420416e6f74686572    |    205065726c204861636b6572
    I wear my Geek Code on my finger.
RE: Can perl do...?
by Anonymous Monk on Jun 05, 2000 at 15:13 UTC
    ($foo = "one two three") =~ s/two/2/; This does what you want I think - although why you woud do this, unless the s// was generated on the fly

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://16275]
Approved by root
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (4)
As of 2023-12-09 12:15 GMT
Find Nodes?
    Voting Booth?
    What's your preferred 'use VERSION' for new CPAN modules in 2023?

    Results (38 votes). Check out past polls.