sub csv_split { # This is very elegant. It handles one concept and does so in a simple and # clear fashion. # Two bugs: # 1) use "return;", not "return undef;". The latter creates a one element # list in list context. # 2) I would use "shift // return;" (if you have the patch). Otherwise, # your function won't handle "0.0" correctly. If you don't have the # patch, I would do a defined-check. local $_ = shift || return undef; my @array = (); # This is not elegant - it's cute and clever. You're using 0 in both its # numeric and boolean aspects. Now, you may not have a choice in the matter, # as Perl may not give you the tools to be elegant. (It might ...) my $count = my $quoted = 0; # The while definition is elegant - simple, understated, but clear. But, the # use of $1 throughout the loop is definitely not elegant. It's kinda ugly. # Again, I'm not sure Perl gives you the tools to do the elegant thing here. while ( s/(.)// ) { if ($1 eq ',' && !$quoted) { $count++; next; } # The use of q// here is more elegante than '"', but it might have been # better to provide a variable that hides the ugliness. if ($1 eq q/"/) { # The "$x = 1 - $x" idiom is very elegant. I've always liked it. unless ( $quoted && s/^\"// ) { $quoted = 1 - $quoted; next; } } $array[$count] .= $1; } # Elegance might demand a wantarray solution here. It's unclear. @array; } #### sub csv_split { local $_ = shift // return; my $is_quoted; my $count = my @array; while ( s/(.)// ) { if ($1 eq ',' and not $is_quoted) { $count++; } elsif ($1 eq q/"/ and not ( $is_quoted and s/^\"// )) { $is_quoted = !$is_quoted; } else { $array[$count] .= $1; } } return if $is_quoted; wantarray ? @array : \@array; }