For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > September 2004 > How to slice a split directly?









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author How to slice a split directly?
Siegfried Heintze

2004-09-23, 8:57 pm

This works and does what I want it to:

perl -e '@x = split("\\.", "a.b.c"); print $x[0];'

Why does not this work?
perl -e 'print @{split("\\.", "a.b.c")}[0];'

Is there a compact way to take a slice of a split (or other function that
returns an array) without creating a temporary variable?

Thanks,
Siegfried

William Gunther

2004-09-23, 8:57 pm

On Thu, 23 Sep 2004 13:43:08 -0600, Siegfried Heintze
<siegfried@heintze.com> wrote:
> This works and does what I want it to:
>
> perl -e '@x = split("\\.", "a.b.c"); print $x[0];'
>
> Why does not this work?
> perl -e 'print @{split("\\.", "a.b.c")}[0];'


Because split doesn't return an array reference, it returns a list.

print( (split(/\./, "a.b.c"))[0] );

>
> Is there a compact way to take a slice of a split (or other function that
> returns an array) without creating a temporary variable?
>
> Thanks,
> Siegfried
>
> --
> To unsubscribe, e-mail: beginners-unsubscribe@perl.org
> For additional commands, e-mail: beginners-help@perl.org
> <http://learn.perl.org/> <http://learn.perl.org/first-response>
>
>




--
-will
http://www.wgunther.tk
(the above message is double rot13 encoded for security reasons)

Most Useful Perl Modules
-strict
-warnings
-Devel::DProf
-Benchmark
-B::Deparse
-Data::Dumper
-Clone
-Perl::Tidy
-Beautifier
-DBD::SQLite
Jenda Krynicky

2004-09-23, 8:57 pm

From: "Siegfried Heintze" <siegfried@heintze.com>
> This works and does what I want it to:
>
> perl -e '@x = split("\\.", "a.b.c"); print $x[0];'
>
> Why does not this work?
> perl -e 'print @{split("\\.", "a.b.c")}[0];'
>
> Is there a compact way to take a slice of a split (or other function
> that returns an array) without creating a temporary variable?


perl -e 'print ((split("\\.", "a.b.c"))[0]);'

It's a bit tricky. The outermost braces belong to print(), the next
ones enclose the call to split() so that it can be sliced and the
innermost enclose the parameters for split(). Only the innermost may
be left out.

This makes the slicing of function result a bit clearer I think:

($hour, $minute, $sec) = (localtime())[2,1,0];

Jenda
===== Jenda@Krynicky.cz === http://Jenda.Krynicky.cz =====
When it comes to wine, women and song, wizards are allowed
to get drunk and croon as much as they like.
-- Terry Pratchett in Sourcery

Wiggins d Anconia

2004-09-23, 8:57 pm

> This works and does what I want it to:
>
> perl -e '@x = split("\\.", "a.b.c"); print $x[0];'
>
> Why does not this work?
> perl -e 'print @{split("\\.", "a.b.c")}[0];'
>
> Is there a compact way to take a slice of a split (or other function that
> returns an array) without creating a temporary variable?
>
> Thanks,
> Siegfried
>


Sometimes when working out this kind of detail it is helpful to make a
full script and activate strict/warnings. In the above case you get the
following,

> perl -Mstrict -w -e 'print @{split("\\.", "a.b.c")}[0];'

Use of implicit split to @_ is deprecated at -e line 1.
Can't use string ("3") as an ARRAY ref while "strict refs" in use at -e
line 1.

Essentially C<split> returns a list, the construct C<@{ }> is a way to
slice into a hash, which you don't have. So you need to slice into a
list, which in this case is done like,

perl -Mstrict -w -e 'print ((split("\\.", "a.b.c"))[0]);'

Notice the extra set of parens, otherwise you get a syntax error because
C<print> would otherwise use the first set as an argument list.

HTH,

http://danconia.org
Jenda Krynicky

2004-09-23, 8:57 pm

From: "Wiggins d Anconia" <wiggins@danconia.org>
>
> Sometimes when working out this kind of detail it is helpful to make a
> full script and activate strict/warnings. In the above case you get
> the following,
>
> Use of implicit split to @_ is deprecated at -e line 1.
> Can't use string ("3") as an ARRAY ref while "strict refs" in use at
> -e line 1.
>
> Essentially C<split> returns a list, the construct C<@{ }> is a way to
> slice into a hash, which you don't have.


There'd have to be a name of a variable between the @ and the opening
curly brace for that to be a hash slice. This way its an array
dereference:

@arr = (1,2,3);
$rArr = \@arr;
@other = @{$rArr};

Of course in this case you do not need the braces.

You'd use the @{} if the thing you need to dereference is more
complex, for example if you need to dereference a function result.

So
print join(', ', @{function('returning', 'arrayref')});
would be correct, just like
print join(', ', @{function('returning', 'arrayref')}[1,2,4,7]);

If you'd want just one item from the referenced array you would of
course use ${}[] instead:

print ${function('returning', 'arrayref')}[2];

In this case the function doesn't return a reference, but a list so
there is no point in trying to dereference anything :-)

This is where the "Can't use string ("3") as an ARRAY ref while
"strict refs" in use at -e line 1." message comes from. The split()
is evaluated in scalar context and thus returns the number of
elements found in the string. And then the code tries to do this:

perl -e 'print @{3}[0];'

Jenda
===== Jenda@Krynicky.cz === http://Jenda.Krynicky.cz =====
When it comes to wine, women and song, wizards are allowed
to get drunk and croon as much as they like.
-- Terry Pratchett in Sourcery

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com