Hi,

I was about to ask the question how to reverse a string but luckily (nah - because of discipline), i searched PM before: This node explains how you can achieve it. Why didn't it work for me? Well because Perl tricked me badly.

Of course I tried a
my $str = "Hello"; print reverse $str;
Nothing happened. Scalar context scalar context... $str is a scalar no? ;-)

Then I had a look at the Perl Cookbook and the solution "processing a string one character at a time" involved the creation of a list, which isn't acceptable because I have to reverse whole files (can do so in memory, but not with the file in a scalar AND splitted each byte in a list).

I then ended up with a solution that worked but instantly didn't feel perlish:

sub rev_scalar { my $data = shift; my $i; my $tmp; for($i = 0; $i < int(length($$data)/2); $i++) { $tmp = substr($$data,$i,1); substr($$data,$i,1) = substr($$data,-($i+1),1); substr($$data,-($i+1),1) = $tmp; } }
Ugly isn't it. Simple things should be simple. Therefore there MUST be a better solution in Perl.

reverse is this solution, but I didn't see it because I tested it within print which - I suppose - puts the whole thing into list context.

Ah well. So a  print scalar(reverse $str); should work. And it does. And now is time to admit, that whatever skills I may have reached in Perl, I still haven't sufficient intuition about the list/scalar context thing.

Bye
 PetaMem
    All Perl:   MT, NLP, NLU

Replies are listed 'Best First'.
Re: How to reverse a string *revisited*
by PodMaster (Abbot) on Nov 11, 2003 at 09:54 UTC
    And it does. And now is time to admit, that whatever skills I may have reached in Perl, I still haven't sufficient intuition about the list/scalar context thing.
    No intuition neccessary ;)-> "List" is a Four-Letter Word

    MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
    I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
    ** The third rule of perl club is a statement of fact: pod is sexy.

Re: How to reverse a string *revisited*
by Zaxo (Archbishop) on Nov 12, 2003 at 01:03 UTC

    What puts things in list context is print, not the arguments themselves in print reverse $str;. The scalar builtin puts its argument in scalar context. Try print scalar reverse $str;

    After Compline,
    Zaxo

      Yeah, and compare the subtle difference between the following two lines:
      print "", reverse $str; print "". reverse $str;

      Abigail

Re: How to reverse a string *revisited*
by liz (Monsignor) on Nov 11, 2003 at 09:41 UTC
    And don't forget there's the reverse of scalar()
    ()
    which provides array context:

    my $foo = (1,1,1,1,1); my $bar = () = (1,1,1,1,1); print "foo = $foo, bar = $bar\n"; __END__ foo = 1, bar = 5

    Liz

    Update:
    Please check out Abigail-II's and AM's corrections to my poor understanding/wording of this feature of Perl and how it is used in some nice Perl idioms.

      Well, that's a dangerous thing to say. Already there are way to many people thinking that dumping a set of parens around an expression puts that expression into list context. That isn't true. In your example, it's the fact that there is a list on the LHS which makes list context.
      #!/usr/bin/perl use strict; use warnings; sub f { print wantarray ? "LIST\n" : defined wantarray ? "SCALAR\n" : "VOI +D\n" } (f); my $foo = (f); my @foo = f; __END__ VOID SCALAR LIST

      Abigail

      There is no such thing as array context, that's a list in scalar context ;) read perldoc perldata

      List assignment in scalar context returns the number of elements produced by the expression on the right side of the assignment:

      $x = (($foo,$bar) = (3,2,1)); # set $x to 3, not 2 $x = (($foo,$bar) = f()); # set $x to f()'s return count
      This is handy when you want to do a list assignment in a Boolean context, because most list functions return a null list when finished, which when assigned produces a 0, which is interpreted as FALSE.

      It's also the source of a useful idiom for executing a function or performing an operation in list context and then counting the number of return values, by assigning to an empty list and then using that assignment in scalar context. For example, this code:

      $count = () = $string =~ /\d+/g;
        There is no such thing as array context, that's a list in scalar context ;)

        There's no such this as a list in scalar context. ;-)

        From perlop - Comma Operator:

        Binary ``,'' is the comma operator. In scalar context it evaluates its left argument, throws that value away, then evaluates its right argument and returns that value.
        In list context, it's just the list argument separator, and inserts both its arguments into the list.
        ihb
Re: How to reverse a string *revisited*
by Aristotle (Chancellor) on Nov 11, 2003 at 20:13 UTC
    Ignoring the fact we have reverse just because: a more Perlish way to write that function is
    sub rev_scalar { local $_ = shift; return if not defined; my $res = ''; $res .= chop while length; return $res; }

    Makeshifts last the longest.

Re: How to reverse a string *revisited*
by Anonymous Monk on Nov 11, 2003 at 23:40 UTC
    #or, to be only slightly less ugly sub rev_scalar { my $data = shift; my $i; for($i = 0; $i < int(length($$data)/2); $i++) { (substr($$data,$i,1),substr($$data,-($i+1),1) = (substr($$data,-($i+1),1)substr($$data,$i,1)); } }