views:

691

answers:

4

When I say simple, I mean, within an expression, so that I can stick it in as a value in a hash without preparing it first. I'll post my solution but I'm looking for a better one that reminds me less of VB. :)

A: 
substr($s, 0, index($s, $/) > -1 ? index($s, $/) || () )
Kev
LOL, oops...thanks!
Kev
+9  A: 

How about

( split /\n/, $s )[0]

?

You don't have to worry about \n being not cross-platform because Perl is clever enough to take care of that.

innaM
Thanks, that's what I was looking for! I look forward to reading that article too, since I've had issues with linebreaks in the past, but perhaps it wasn't Perl's fault.
Kev
Well, Perl makes \n mean different things on different systems, but that doesn't mean that \n is the record separator for the input. :)
brian d foy
And, let's just hope that this string isn't huge :)
brian d foy
Good point, Brian...in this case it's not, it's just an error message.
Kev
Have you ever tried using 1 as the third parameter to split? What do you think split should do when told to produce only one element? You need to split into at least two elements, and even then, you end up with a list that still contains most of the data from the string.
brian d foy
You're right Brian, passing 1 as the third parameter causes the entire original string to be returned. I shoulda read the docs more carefully. All I can say in my defense is that that's not what *I* think split() should do.
j_random_hacker
+1  A: 

This isn't as simple as you like, but being simple just to be short shouldn't always be the goal.

You can open a filehandle on a string (as a scalar reference) and treat it as a file to read the first line:

my $string = "Fred\nWilma\Betty\n";
open my($fh), "<", \$string or die ...; # reading from the data in $string
my $first_line = <$fh>; # gives "Fred"
close $fh;

If you really wanted to, I guess you could reduce this to an expression:

$hash{$key} = do { open my($fh), "&lt;", \$string; scalar <$fh> };

No matter which method you choose, you can always make a subroutine to return the first line and then use the subroutine call in your hash assignment.

sub gimme_first_line { ... }

$hash{$key } = gimme_first_line( \$string );
brian d foy
Except this multi-line string is not stored in a file...
Kev
No, it's a string in memory. You can treat it like a file though.
brian d foy
Oops, I didn't read your code very carefully. Huh, I didn't know you could do that!
Kev
+1 for teaching me a new trick :)
Brian Rasmussen
+1  A: 
($str =~ /\A(.*?)$/ms)[0];

For large strings, this will be faster than

(split /\n/, $str)[0]

as suggested by Manni. [Edit: removed erroneous mention of split /\n/, $str, 1.]

If you want to include the terminal \n if it is present, add \n? just before the closing paren in the regex.

j_random_hacker