Ex-Perl coders: Howz it feel to convert to Ruby?

B

Brian Wisti

--- Lennon Day-Reynolds said:
[...]
Very interesting... I don't know where your "area" is, where is all this
happening?

Curt

Portland, OR, and the surrounding 'burbs. I'm working at Intel using
Ruby right now, (in a position which Phil vacated a few months ago)
and we're looking to hire another coder to work with me. We're not
the
only group in-house using Ruby either; we're just (AFAIK) the first
of
be hiring Ruby coders specifically.

Man, why can't you guys be up here in Seattle? It's just a few miles
away. I'm sure Intel can move every building, person, and project up
here.

You know we're the cool kids, right? ;-)

-- Brian Wisti
 
D

David A. Black

Hi --

(3) Another contrived example, this time in Ruby:

def Contrived
3.times { yield }
end

[ "tic", "tac", "toe" ].each do |item|
Contrived { printf "%s ", item }
printf "\n"
end

There is a lot about this that is different than Perl IMO. I could
create an anonymous subroutine in Perl to function something like the
yield block, and I realize the Ruby above is itself somewhat contrived,
but... still, you wouldn't normally do something like this in Perl
whereas in Ruby, these sorts of things are actually useful.

Well, I would do:

puts ["tic", "tac", "toe"]

or

puts %w{ tic tac toe }

but I know you meant it just as an illustration of yield :) (But
still it's always a pleasure to see how compact and clean Ruby can
be.)
## My favorite "Rubyism" I use all the time in Perl -- puts()!

sub puts { for (@_) { print "$_\n" } }

A perhaps slightly pedantic point: this isn't what puts actually does.
It adds a "\n" to the end of the string only if one isn't there
already.


David
 
P

Phil Tomson

(4) Each language has it's own strengths. IMO one of Perl's strengths
is the simplicity and consistency of it's parameter passing:

sub shell {

my @output;
for (@_) { push @output, `$_` }
chomp( @output );
return wantarray ? @output : \@output;

}

Actually, I think this is one of the _worst_ things about Perl and it was
one of those nagging little annoyances that when added up finally led me
to seek out alternatives. The problem with the way parameters are passed
to subroutines in Perl is that you can't tell from a glance how many
params are supposed to be passed into the subroutine and you have no
information about what the params are. You've got to look down through
the subroutine code to see if there's a 'shift @_' lurking somewhere in
the code (for the uninitiated, you pass params to Perl subroutines via the
'@_' global list; you have to 'manually' shift the params off of that list
- blech! )


Phil
 
P

Phil Tomson

Phil Tomson

Very interesting... I don't know where your "area" is, where is all this
happening?

Hillsboro, OR. The job was been advertised on this list a couple of weeks
ago - it may be filled by now. The jobs related to that other link are
in Seatle.

Phil
 
P

Phil Tomson

--- Lennon Day-Reynolds said:
[...]
Very interesting... I don't know where your "area" is, where is all this
happening?

Curt

Portland, OR, and the surrounding 'burbs. I'm working at Intel using
Ruby right now, (in a position which Phil vacated a few months ago)
and we're looking to hire another coder to work with me. We're not
the
only group in-house using Ruby either; we're just (AFAIK) the first
of
be hiring Ruby coders specifically.

Man, why can't you guys be up here in Seattle? It's just a few miles
away. I'm sure Intel can move every building, person, and project up
here.

Those Robot Co-op Ruby jobs are in Seattle. Check the link:
http://robotcoop.com/?c=Open+Positions
That place looks really cool: hardwood floors and windows that actually
open to the outside ... Powerbooks... and they seem to be using Ruby.

Once again our region leads the nation in forward thinking ;-)
You know we're the cool kids, right? ;-)

Of course. Portlanders always secretly worry that Seattle-ites are
cooler than us ;-)

Phil
 
P

Phil Tomson

That's something that shouldn't be overlooked -

when I went back to perldoc after maybe 9 months away from Perl I had
major problebs remembering the right function to do a particular bit
of manipulation on a Hash. perldoc -f isn't much use without a method name,
and even Google is only useful if can say what you want :)

With Ruby it was just 'ri Hash;ri Enumerable' to see all the methods
that worked on a Hash.

Or in irb:
Array.methods.sort
=> ["&", "*", "+", "-", "<<", "<=>", "==", "===", "=~", "[]", "[]=",
"__id__", "__send__", "all?", "any?", "assoc", "at", "class", "clear",
"clone", "collect", "collect!", "compact", "compact!", "concat", "delete",
"delete_at", "delete_if", "detect", "display", "dup", "each",
"each_index", "each_with_index", "empty?", "entries", "eql?", "equal?",
"extend", "fetch", "fill", "find", "find_all", "first", "flatten",
"flatten!", "freeze", "frozen?", "grep", "hash", "id", "include?",
"index", "indexes", "indices", "inject", "insert", "inspect",
"instance_eval", "instance_of?", "instance_variable_get",
"instance_variable_set", "instance_variables", "is_a?", "join",
"kind_of?", "last", "length", "map", "map!", "max", "member?", "method",
"methods", "min", "nil?", "nitems", "object_id", "pack", "partition",
"pop", "private_methods", "protected_methods", "public_methods", "push",
"rassoc", "reject", "reject!", "replace", "respond_to?", "reverse",
"reverse!", "reverse_each", "rindex", "select", "send", "shift",
"singleton_methods", "size", "slice", "slice!", "sort", "sort!",
"sort_by", "taint", "tainted?", "to_a", "to_ary", "to_s", "transpose",
"type", "uniq", "uniq!", "unshift", "untaint", "values_at", "zip", "|"]

It may not give you all the information about each method, but you can
often get a pretty good idea from the name - if not, then you can use ri
to figure it out.

Phil
 
B

Bill Kelly

In ruby that might be,

def shell(*args)
args.map {|a| `#{a}`.chomp}
end

...It's true you'll always get an array back. But if
you want to splat the array such that you can assign
its individual element(s) to variables you can...

a = shell("echo 1", "echo 2") # a => ["1", "2"]
a,b = *shell("echo 1", "echo 2") # a => "1", b => "2"


Regards,

Bill
 
B

Brian Wisti

Or in irb:
Array.methods.sort
=> ["&", "*", "+", "-", "<<", "<=>", "==", "===", "=~", "[]", "[]=",
"__id__", "__send__", "all?", "any?", "assoc", "at", "class",
"clear",
"clone", "collect", "collect!", "compact", "compact!", "concat",
"delete",
"delete_at", "delete_if", "detect", "display", "dup", "each",
"each_index", "each_with_index", "empty?", "entries", "eql?",
"equal?",
"extend", "fetch", "fill", "find", "find_all", "first", "flatten",
"flatten!", "freeze", "frozen?", "grep", "hash", "id", "include?",
"index", "indexes", "indices", "inject", "insert", "inspect",
"instance_eval", "instance_of?", "instance_variable_get",
"instance_variable_set", "instance_variables", "is_a?", "join",
"kind_of?", "last", "length", "map", "map!", "max", "member?",
"method",
"methods", "min", "nil?", "nitems", "object_id", "pack", "partition",

"pop", "private_methods", "protected_methods", "public_methods",
"push",
"rassoc", "reject", "reject!", "replace", "respond_to?", "reverse",
"reverse!", "reverse_each", "rindex", "select", "send", "shift",
"singleton_methods", "size", "slice", "slice!", "sort", "sort!",
"sort_by", "taint", "tainted?", "to_a", "to_ary", "to_s",
"transpose",
"type", "uniq", "uniq!", "unshift", "untaint", "values_at", "zip",
"|"]

It may not give you all the information about each method, but you
can
often get a pretty good idea from the name - if not, then you can use
ri
to figure it out.

This is one of those situations where I kinda miss Python and its
ability to store and later display the docstring of a function or class
when requested.

One thing at a time, I suppose.

-- Brian Wisti
 
J

Joel VanderWerf

This is one of those situations where I kinda miss Python and its
ability to store and later display the docstring of a function or class
when requested.

One thing at a time, I suppose.

Why bloat the ruby executable with docstrings when you can easily add ri
to irb? After all, irb is where you want to access the docs. Here's the
relevant part of my .irbrc:

def ri arg
puts `ri #{arg}`
end

class Module
def ri(meth=nil)
if meth
if instance_methods(false).include? meth.to_s
puts `ri #{self}##{meth}`
end
else
puts `ri #{self}`
end
end
end
 
C

Charles Mills

Why bloat the ruby executable with docstrings when you can easily add
ri to irb? After all, irb is where you want to access the docs. Here's
the relevant part of my .irbrc:

def ri arg
puts `ri #{arg}`
end

class Module
def ri(meth=nil)
if meth
if instance_methods(false).include? meth.to_s
puts `ri #{self}##{meth}`
end
else
puts `ri #{self}`
end
end
end

Very cool.
Over here in Portland (where there are lots of Ruby jobs and everyone
is happy) we were talking about working on an *enhanced* version of irb
that would support some/all of the stuff you see here:
http://ipython.scipy.org/ (scroll down to Main Features)
Hasn't gone anywhere though, but I am still pretty excited about the
idea.
IMHO some type of irb addition which groups statements by blocks
instead of by lines would be nice. So when you press 'up' you cycle
through the blocks in your history rather than the individual lines.
(by block I mean if .... end, do .... end, etc) Seems like it would
have to be more than a drop in readline replacement, since it would
have to allow multiline editing of the blocks in history.

Hope that made sense,
Charlie
 
C

ChrisO

Brian said:
Hmm ... TMTOWTDI applies in both Perl and Ruby. I think I would have
written most of your examples differently, and that difference is



foreach my $i (0..9) { do_something_with($i) }

You know, a stylistic thing for sure, but I've stopped using "foreach"
and just use "for" everywhere. And if I can get away with using $_, I
do in lieu of the "my $i" unless I have inner loops and I need a
variable to ferret out abiguity. But I'm OT here, discussing Perl sytle
in a Ruby NG.
or even

map { do_something_with($_) } (0..9);




0.upto(9) { |i| do_something_with(i) }




True enough, but presumably your understanding deepends as you go
deeper into Ruby, yes?

I would agree with that.
Sure, but POLS is a decent guideline, and when all else fails I call
obj.methods() from irb to see what I get to play with. I generally
don't need to refer to docs for libraries that I haven't imported, so
I'm not sure I understand that bit.

irb is nice just as "perl -e" on the command line is for checking out
features. I've done both as well as "ruby -e".
And maybe things aren't as straightforward in Perl as you describe. One
still has to be familiar with the full standard library, the various
sigils, the built-in types, and all of the modules that you've
imported.

I can't argue too much that Perl is kind of it's own thing too, yes.
But it's still easy to keep completely procedural and I would say a
large amount of Perl that I see is.
(3) Another contrived example, this time in Ruby:

def Contrived
3.times { yield }
end

[ "tic", "tac", "toe" ].each do |item|
Contrived { printf "%s ", item }
printf "\n"
end

There is a lot about this that is different than Perl IMO. I could
create an anonymous subroutine in Perl to function something like the

yield block, and I realize the Ruby above is itself somewhat
contrived,
but... still, you wouldn't normally do something like this in Perl
whereas in Ruby, these sorts of things are actually useful.


Useful, sure. Widely used, you betcha. Fact is that I've still never
needed to use yield in any production code. Use what you need, not what
you feel like you're supposed to. Your sample Perl code didn't show
taint-checking or full conformance to strict and warnings, even though
that is widely promoted as the "right way" to do things.

(4) Each language has it's own strengths. IMO one of Perl's
strengths
is the simplicity and consistency of it's parameter passing:

sub shell {

my @output;
for (@_) { push @output, `$_` }
chomp( @output );
return wantarray ? @output : \@output;

}

## My favorite "Rubyism" I use all the time in Perl -- puts()!

sub puts { for (@_) { print "$_\n" } }

puts( shell(
"ls -l",
"ps -ef | grep -i foo",
"rm *.bar",
));


Yup, it's a strength of Perl, and that's a nifty puts subroutine :)

Thanks. It's tremendously useful for a ton of things written this way.
I still find uses for it that surprise and delight, not to mention
that I have "puts()" in every language I use -- C, JavaScript, Perl, VB,
WSH, etc. I don't even have to remember any more, except I can't do the
above (with the array as a parameter) in anything but Perl.
What's wrong with taking advantage of the languages that Ruby builds
on? Familiarity with Perl, Python, Smalltalk, and LISP are all
incredibly useful with Ruby, and sometimes a design is easiest to
express in something resembling one of those languages.

I can see a problem with trying to make your Ruby code look *exactly*
like Perl code, same as writing a C-style for(;;) loop instead of a
for/foreach loop in Perl is ugly. But hey, sometimes it's useful. I
don't knock what works, as long as I can read it :)




Sure, it's not the same. But insisting on doing things the "Ruby Way"
immediately is naturally going to result in a serious dip in
productivity compared to going out and writing code that works, right
away.

This is a perspective I need to adopt more, for sure. It's probably the
only realistic way and was exactly the same way I learned Perl. I
didn't develop that puts() call above overnight, as simple as it is,
simply because my ability to conceptualize it that easily didn't exist
until after I had written a significant amount of code. The same will
be true for Ruby.

-ceo
 
C

ChrisO

David said:
Hi --

(3) Another contrived example, this time in Ruby:

def Contrived
3.times { yield }
end

[ "tic", "tac", "toe" ].each do |item|
Contrived { printf "%s ", item }
printf "\n"
end

There is a lot about this that is different than Perl IMO. I could
create an anonymous subroutine in Perl to function something like the
yield block, and I realize the Ruby above is itself somewhat contrived,
but... still, you wouldn't normally do something like this in Perl
whereas in Ruby, these sorts of things are actually useful.


Well, I would do:

puts ["tic", "tac", "toe"]

or

puts %w{ tic tac toe }

but I know you meant it just as an illustration of yield :)
Yep!

(But
still it's always a pleasure to see how compact and clean Ruby can
be.)

Yep (again).
A perhaps slightly pedantic point: this isn't what puts actually does.
It adds a "\n" to the end of the string only if one isn't there
already.

You know, I didn't discover that until this week on my re-entry into
Ruby... But I'd say 95% of the time I use puts in Ruby, it's without
the "\n" at the end, so in Perl I like having the same behavior.

-ceo
 
C

ChrisO

Phil said:
Actually, I think this is one of the _worst_ things about Perl and it was
one of those nagging little annoyances that when added up finally led me
to seek out alternatives. The problem with the way parameters are passed
to subroutines in Perl is that you can't tell from a glance how many
params are supposed to be passed into the subroutine and you have no
information about what the params are. You've got to look down through
the subroutine code to see if there's a 'shift @_' lurking somewhere in
the code (for the uninitiated, you pass params to Perl subroutines via the
'@_' global list; you have to 'manually' shift the params off of that list
- blech! )

An incredibly interesting point of view though your justification for it
is somewhat understandable. Pathological mistakes can occur this way
for those that use this, what I would call an incredibly nice feature,
in an undisciplined way. I'm quite disciplined about spiking out my
arguments in Perl at the top of a subroutine. I think your dislike
perhaps has been fueled by people that write subroutines in a "hackish"
sort of way. (I would imagine "hacking" Ruby is just as possible to
accomplish.)

But aside from the undisciplined uses you've pointed out as reason for
eshewing this in Perl, I have to wholy stand by the amazing power this
feature brings. It far outweighs the negatives. It's one of the
"genius" things about Perl. (Always educational, however, to get
someone else's opposite point of view, as you have offered.)

And to bring this Perl discussion back on topic, in line with your
dislike of this "feature" in Perl, am I not correct in understanding
that in Ruby, one can create methods on the fly in a class? How is this
that much different (conceptually) than unspecified parameters in a Perl
subroutine? How do you know what methods are there (aside from using
the inspection methods available to every class [unless I am mistaken in
this regard]).

-ceo
 
C

ChrisO

Phil said:
Actually things are changing. This place is hiring Ruby programmers for
Rails work, for example:
http://robotcoop.com/

I know of another Ruby job that is probably still open in my area as well.

I'd vote for making a clean break from Perl. It might be that learning
Ruby and Rails will actually turn out to be a good career move (let's
hope).

Actually, you've voiced something openly here that I am privately
hoping. It's getting more and more difficult to keep my rates up when
people can place jobs out for bid and have someone in India or Russia
with an Masters degree in Computer Science complete the work in PHP,
Perl or Java for rates that I can't touch. I'm hoping to tap into a
"niche" market. One that perhaps doesn't exist yet, but maybe it
should. Ruby is really incredible IMO. If I had have a chance of
bringing it into my full-time workplace, I most certainly would. Maybe
down the road, which is precisely the point.

-ceo
 
G

Gavin Sinclair

Absolutely. One of my primary intriques with Ruby, to be sure...

In that case, I suggest you simply read Pickaxe II for pleasure. It's
a good survey of how to accomplish things in Ruby, and the available
libraries to help you.

By the time you finish, you'll have enjoyed thinking differently and
picked up enough Ruby idioms to know what's going on.

Cheers,
Gavin
 
L

Lothar Scholz

Hello ChrisO,

I agree with Phil that the unspecified parameters is one of the worst
things in Perl.

C> But aside from the undisciplined uses you've pointed out as reason for
C> eshewing this in Perl, I have to wholy stand by the amazing power this
C> feature brings. It far outweighs the negatives. It's one of the
C> "genius" things about Perl. (Always educational, however, to get
C> someone else's opposite point of view, as you have offered.)

I don't care if you are disciplined enough and can do nice hacks with
this "genius" things. Software is written and maintained by a lot of
different people. If you have to read other persons source code you
are normally lost. I have once seen the argument that a brush
shouldn't restrict the work of painter, and so a language shouldn't
restrict the work of a "genius" programmer but i don't agree with this.

Enforcing styles is good and more productive in the long run.

C> And to bring this Perl discussion back on topic, in line with your
C> dislike of this "feature" in Perl, am I not correct in understanding
C> that in Ruby, one can create methods on the fly in a class? How is this
C> that much different (conceptually) than unspecified parameters in a Perl
C> subroutine? How do you know what methods are there (aside from using
C> the inspection methods available to every class [unless I am mistaken in
C> this regard]).

The difference is that the Ruby method is only used in very very
special cases and should not be seen a good style of programming
without good reasons. I think the TK bindings source code is a good example to
not use this feature. But the perl solution is something that you
must use all the time. So you can't compare the two cases.
 
C

ChrisO

Brian said:
What's the payoff using Ruby instead of Perl? For me, the end result is
stress reduction. It takes roughly the same amount of effort to create
a small program in the two languages, but progressively less effort to
create Ruby applications as the size and scope of the app increases.
The Principle of Least Surprise means that most things are done like
you would expect them to be (or at least like Matz expects them to be,
which is still more consistent than most languages out there).

It is nice to have legible code, too. I know that "legible" is entirely
subjective, and you don't have to agree with it if you don't want to.
You can make clean code in Perl, but it takes a little more work and a
lot more discipline. Plus, all of the "my/local/our" stuff and shifting
subroutine arguments and list context vs. scalar context (and, and,
..) in Perl starts to look more than a little extraneous, interfering
with your reading of the actual code logic. Since Ruby doesn't use any
of that stuff, it's easier for me to see the meat of the code.

I'm seeing this claim more and more and I'm starting to get sold. Where
there's smoke, there's fire. Multiple people can't be saying this sort
of thing for no reason.

-ceo
 
C

ChrisO

Phil said:
Dick Davies said:
That's something that shouldn't be overlooked -

when I went back to perldoc after maybe 9 months away from Perl I had
major problebs remembering the right function to do a particular bit
of manipulation on a Hash. perldoc -f isn't much use without a method name,
and even Google is only useful if can say what you want :)

With Ruby it was just 'ri Hash;ri Enumerable' to see all the methods
that worked on a Hash.


Or in irb:
Array.methods.sort
=> ["&", "*", "+", "-", "<<", "<=>", "==", "===", "=~", "[]", "[]=",
"__id__", "__send__", "all?", "any?", "assoc", "at", "class", "clear",
"clone", "collect", "collect!", "compact", "compact!", "concat", "delete",
"delete_at", "delete_if", "detect", "display", "dup", "each",
"each_index", "each_with_index", "empty?", "entries", "eql?", "equal?",
"extend", "fetch", "fill", "find", "find_all", "first", "flatten",
"flatten!", "freeze", "frozen?", "grep", "hash", "id", "include?",
"index", "indexes", "indices", "inject", "insert", "inspect",
"instance_eval", "instance_of?", "instance_variable_get",
"instance_variable_set", "instance_variables", "is_a?", "join",
"kind_of?", "last", "length", "map", "map!", "max", "member?", "method",
"methods", "min", "nil?", "nitems", "object_id", "pack", "partition",
"pop", "private_methods", "protected_methods", "public_methods", "push",
"rassoc", "reject", "reject!", "replace", "respond_to?", "reverse",
"reverse!", "reverse_each", "rindex", "select", "send", "shift",
"singleton_methods", "size", "slice", "slice!", "sort", "sort!",
"sort_by", "taint", "tainted?", "to_a", "to_ary", "to_s", "transpose",
"type", "uniq", "uniq!", "unshift", "untaint", "values_at", "zip", "|"]

More "Wow!" You can't do this in Perl (unless you call in another CPAN
module to pick apart another module. Hardly compariable.)

I becoming quite glad I've started this discussion. I'm thinking I'm
just about taken in with this. Beautiful.

-ceo
 
C

ChrisO

Andrew said:
I'll throw my $0.02 into the pot ...

I wouldn't call myself a "hardcore" anything, but I have used Perl a lot,
written about Perl a good deal, and taught a fair number of Perl courses
(introductory and advanced). I do like Perl.

If you are fluent in Perl and have a good grasp of OO (Perl's and/or other
langauges), then fluency in the Ruby language itself should be a relatively
quick and enjoyable experience. What *will* take a while longer is becoming
familiar enough with what is and isn't available in the standard libraries
or on RAA and rubyforge to become as productive as you currently are in
Perl (but that isn't a "language" issue per se).

Absolutely. I agree.
I will mention that I have tried out Python on a couple of occassions, but
was just never seriously drawn to it.

Ruby, on the other hand, appealed to me right away. As different as Ruby
and Perl are, they both "fit" with how my mind thinks and solves problems
--- and I've always been an advocate of balancing the old axiom of "using
the right tool for the job" with "using the right tool for your mind". Ruby
and Perl are both darn good tools in my mind, and for my mind. So for me it
was worth it, ymmv.

I'm totally with you on all this. I've done *exactly* the same thing
(Python and all), and I'm thinking both Perl and Ruby fit my "thinking"
as well. Good post, mate.

-ceo
 
J

Joel VanderWerf

ChrisO said:
This is where I'm looking to get with Ruby and I still reach for Perl
because I don't know Ruby as well. It happened today at work. I needed
to extract some server names from a piece of Perl code (text) that
looked like this:

{ SERVER => "servername1", SHARE = $Default },
{ SERVER => "servername2", SHARE = $Default },
{ SERVER => "servername3", SHARE = $Default },
{ SERVER => "servername4", SHARE = $Default },
{ SERVER => "servername5", SHARE = $Default },
{ SERVER => "servername6", SHARE = $Default },
{ SERVER => "servername7", SHARE = $Default },
{ SERVER => "servername8", SHARE = $Default },

(The server names were more unique than the contrived names above.) In
Perl it was:

perl -e 'while (<>) { /"(\w*)"/; print "$1\n" }' file-snippet.txt

In Ruby? I didn't have the time to figure it out. Which is the
agonizing point. Later, I did the following in Ruby to satisfactory
effect:

ruby -e 'ARGF.each { |line| line.scan( /"(\w*)"/ ) { |frag| puts frag }
}' file-snippet.txt

Perhaps someone can refine this while we're at it. It's hard not to
notice that the Perl was more concise. Perhaps my ignorance can be made
right...? Can this be shortened in Ruby? Surely...

Golf.shoes = "on"

$ ruby -n -e 'puts $1 if /"(\w+)"/' file-snippet.txt
servername1
servername2
servername3
servername4
servername5
servername6
servername7
servername8
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top