Perl traps for Ruby Programmers

To list in the next Camel the gotchas Ruby programmers might have run into with Perl, I've really had to dust off my Ruby skills, few as they are. I got a lot of good feedback for my Perl traps for Python Programmers, both public and private, so I'm doing it again for Ruby.

I'm only interested in the practical aspects of a person used to Ruby moving to Perl and the things they might try to do based on their Ruby experience. Also, since we already covered some things in the Python section, I'm not going to repeat some of the items.

Several Perl people have good Ruby experience, so please check my work and suggest what I've left out.

=over 4

=item *

There's no B>irb>. See the Python section.

=item *

Perl just has numbers. It doesn't care if they have fractional
portions or not.

=item *

You don't need to surround variables with C>{}> to interpolate them,
unless you need to disambiguate the identifier from the string around
it:

"My favorite language is $lang"

=item *

Generalized single quoting uses on lowercase I>q>, and generalized
double quoting uses two lowercase I>q>'s:

q(No interpolation for $100)
qq(Interpolation for $animal)

=item *

Not everything is an object. You might like M>autobox> though.

=item *

You need to separate all Perl statements with a C>;>, even if
they are on different lines. The final statement in a block doesn't
need a final C>;>.

=item *

The case of variable names in Perl don't mean anything to B>perl>.

=item *

The sigils don't denote variable type. A C>$> in Perl is a single
item, like C>$scalar>, C>$array[0]>, or C>$hash{$key}>.

=item *

Perl compares strings with C>lt>, C>le>, C>eq>, C>ne>, C>ge>, and
C>gt>.

=item *

No coroutines. Sorry.

=item *

Perl's subroutine definitions are compile-phase. So

use v5.10;
sub foo { say 'Camelia' }
foo();
sub foo { say 'Amelia' };
foo();

This prints C>Amelia> twice because the last definition is in place
before the run phase statements execute. This also means that the call
to a subroutine can appear earlier in the file than the subroutine's
definition.

=item *

Perl doesn't have class variables, but people fake them with lexical variables.

=item *

The range operator in Perl returns a list.

=item *

The C<>/s> pattern modifier makes Perl's C>.> match a newline, whereas
Ruby uses the >/m> for the same thing. The C>/m> in Perl makes the
C>^> and C>$> anchors match at the beginning and end of logical
lines.

=item *

Perl flattens lists.

=item *

Perl's C>> => >> can stand in almost anywhere you can use a comma, so
you'll often see Perler's use the arrow to indication direction:

rename $old => $new;

=item *

In Perl, C>0>, C>'0'>, C>''>, C>()>, and C>undef> are false in
boolean contexts. Basic Perl doesn't require a special boolean
value. You might want the M>boolean> module.

=item *

Perl often fakes the job of C>nil> with an C>undef>.

=item *

Perl allows you to be a bit sloppier because some of the characters
aren't that special. A C>?> after a variable doesn't do anything
to the variable, for instance:

my $flag = $foo? 0:1;

=back

7 Comments

MT seems to have eaten some the POD notation.

Perl strings are strings, not array of chars like in Ruby. In order to process a string as an array of chars, one has to create a list from it:

@array = split(//, $string);
or
@array = unpack("C*", $string);

Personally I would stop after that first sentence, or not mention strings vs arrays altogether.

When you tell Ruby programmers how to write Perl in a Ruby manner, they will... not surprisingly ... write Perl in a Ruby manner.

If anything, perhaps identify particular use cases where Ruby code often manipulates an array of characters, and show the idiomatic Perl equivalent.

Perheap my comment wasn't very interesting. I'm not a programmer. I use Perl. I read some book about Ruby and design pattern on Ruby. I have meet another discrepency between Ruby and Perl.

a0=2
a1=a0
a0=4
puts"display value : a1 = #{a1} , a0 = #{a0}"
=> display value : a1 = 4 , a0 = 4

I understand that's normal result but on perl we don't have same thing. I don't use Moose, Mouse or Moo...

T. DESSOLES: I don't get the same result as you.

>> ruby -v
ruby 1.8.7 (2010-01-10 patchlevel 249) [x86_64-linux]
>> ruby
a0=2
a1=a0
a0=4
puts"display value : a1 = #{a1}, a0 = #{a0}"
^D
display value : a1 = 2, a0 = 4

Also, I don't see any discrepancy between Perl and Ruby.

>> perl -v
This is perl, v5.10.1 (*) built for x86_64-linux-gnu-thread-multi
>> perl
$a0 = 2;
$a1 = $a0;
$a0 = 4;
print "display value : a1 = $a1, a0 = $a0\n";
^D>/pre>
display value : a1 = 2, a0 = 4

"aa" =~ /^a{1}+$/ matches on Ruby.

In Ruby, \h and \H mean \p{Hex} and \P{Hex}, respectively; In Perl they mean \p{VertSpace} and \P{VertSpace} instead.

\p{Age=6.0} is \p{Present_In: 6.0} in Perl -- \p{Age=6.0} will match for characters introduced in Unicode 6.0, -and nothing else-.

[[:space:]] does not match \x{85}.

You can't do character class subtraction and intersection.

\d and friends match much more than ASCII.

There is no \s escape meaning "space" in double quoted strings.

While qw() is the same as %w(), there is no such thing as %W(). Which is a damn shame.

You can't use

Comments embedded in regexs can't have the delimiter in them; Both /\A(?#:foo\)bar)\z/ and
m/
. #This is a comment /
/x
will result in compilation errors.

Perl's support for variable length lookbehind's is a bit worse than Ruby's, sorta. Neither supports (?

(I might have the next bit wrong -- I recall this biting me in my old work, but not the exact details)
Variables are function-scoped in Ruby. So
def whatever
if 1
a = 10
end
puts a
end

Will output 10 -- Whereas the same block in Perl
sub whatever {
if ( 1 ) {
my $a = 10;
}
say $a;
}

Will either die horribly under strict, or output whatever is in the package-scoped variable $a when the function executes.

$x =~ s/// will modify $x in place, like x.sub!would; The equivalent of x.sub is using the /r flag, like $x =~ s///r

Given an array a = [ 1, 2, 3, 4, 5 ], a[1..3] and a[1,3] mean the same thing, and will both return a 3-element array. The equivalent code in Perl, @a[1..3] and @a[1,3], will return a 3 and 2 element list, respectively.

(I could be at this all night... :P)

Ack. One line got eaten. I think that it said
You can't use <<-END_OF_HEREDOC to automagically indent heredocs.

Leave a comment

About brian d foy

user-pic I'm the author of Mastering Perl, and the co-author of Learning Perl (6th Edition), Intermediate Perl, Programming Perl (4th Edition) and Effective Perl Programming (2nd Edition).