Properly using Ruby's specialness

J

J. Cooper

I was recently reading a presentation on "10 things Java programmers
should know about Ruby." Like many similar discourses, it talked about
classes being objects and singleton methods etc. etc. Now, I am familiar
with these different things, but I think I am too stupid to discern
their inherent worth.

1. Open classes. The other day, in a little Blackjack game I wrote in
Ruby, I used this feature to add in a method to the Array class instead
of making a class that inherited from Array and added that method.
However, a) I'm not sure if that was the "right" way and b) I'm not sure
if there is an advantage to that approach over the latter, per se.

2. Singleton methods. I really can't think of a particular example where
I would use this... please help!

3. Blocks. Although now (after some practice and getting used to) these
make sense to me when I use them with methods already designed, I don't
think I have internalized them to the point where I would write my own
methods that accepted them and worked with them. Has anyone else been in
the same boat, or do they usually just "click"?

Thank you and sorry for the noobness,

J
 
J

Jari Williamsson

J. Cooper said:
I was recently reading a presentation on "10 things Java programmers
should know about Ruby." Like many similar discourses, it talked about
classes being objects and singleton methods etc. etc. Now, I am familiar
with these different things, but I think I am too stupid to discern
their inherent worth.

1. Open classes. The other day, in a little Blackjack game I wrote in
Ruby, I used this feature to add in a method to the Array class instead
of making a class that inherited from Array and added that method.
However, a) I'm not sure if that was the "right" way and b) I'm not sure
if there is an advantage to that approach over the latter, per se.

2. Singleton methods. I really can't think of a particular example where
I would use this... please help!

3. Blocks. Although now (after some practice and getting used to) these
make sense to me when I use them with methods already designed, I don't
think I have internalized them to the point where I would write my own
methods that accepted them and worked with them. Has anyone else been in
the same boat, or do they usually just "click"?

Thank you and sorry for the noobness,

It seems like you want to read the book "Design Patterns in Ruby". It
goes into great detail when to use what, and why, and such stuff.


Best regards,

Jari Williamsson
 
J

James Gray

1. Open classes. The other day, in a little Blackjack game I wrote in
Ruby, I used this feature to add in a method to the Array class =20
instead
of making a class that inherited from Array and added that method.
However, a) I'm not sure if that was the "right" way and b) I'm not =20=
sure
if there is an advantage to that approach over the latter, per se.

Open classes are best used sparingly. There are problems with them, =20
of course, in that your code might collide with someone else's code. =20=

The plus though is that all instances of the changed class are =20
suddenly empowered with new methods you can count on. Some good uses, =20=

in my opinion, are:

* Conversion methods =96 I would rather type %w[a b c].to_csv than =20
CSV.generate_line(%w[a b c]. I don't feel there's much danger of =20
namespace collision here either due to the specific types in the =20
method names. Some disagree and feel this is polluting the namespace =20=

though.
* DSL =96 It can often be convenient to make Ruby understand the =20
language of your problem rather than to express your problem in Ruby.
2. Singleton methods. I really can't think of a particular example =20
where
I would use this... please help!

Well, technically you use this feature in Ruby anytime you create a =20
class method. Outside of that, it's another feature best used in =20
moderation. It does have interesting possibilities though. Here's an =20=

example to try and get you thinking in new directions:
def add_counts(array)
counts =3D array.inject(Hash.new(0)) { |c, e| c.merge(e =3D> c[e] =
+ =20
1) }
class << array; self; end.send:)define_method, :counts) do ?> counts
end
end =3D> nil
a =3D Array.new(10) { rand(6) } =3D> [2, 3, 3, 3, 0, 2, 4, 3, 4, 3]
add_counts(a)
=3D> # said:
=3D> {0=3D>1, 2=3D>2, 3=3D>5, 4=3D>2}
3. Blocks. Although now (after some practice and getting used to) =20
these
make sense to me when I use them with methods already designed, I =20
don't
think I have internalized them to the point where I would write my own
methods that accepted them and worked with them. Has anyone else =20
been in
the same boat, or do they usually just "click"?

I wrote about this on my blog a while back. Maybe it will help:

http://blog.grayproductions.net/articles/code_as_a_data_type

James Edward Gray II

James Edward Gray II
 
F

fedzor

I was recently reading a presentation on "10 things Java programmers
should know about Ruby." Like many similar discourses, it talked about
classes being objects and singleton methods etc. etc. Now, I am
familiar
with these different things, but I think I am too stupid to discern
their inherent worth.

1. Open classes. The other day, in a little Blackjack game I wrote in
Ruby, I used this feature to add in a method to the Array class
instead
of making a class that inherited from Array and added that method.
However, a) I'm not sure if that was the "right" way and b) I'm not
sure
if there is an advantage to that approach over the latter, per se.

That was the correct way to do it! The advantage is you can
instantiate an array object like normal ([]), instead of having to do
MyArray.new(3, 4, 5)

2. Singleton methods. I really can't think of a particular example
where
I would use this... please help!

When you would need to add a method into a class, or create a
subclass with a special method BUT the method is only used by one
object (IE, only one instantiation of MyArray).

Also, you should use it when you want methods to be called within a
class but outside of a method definition.
3. Blocks. Although now (after some practice and getting used to)
these
make sense to me when I use them with methods already designed, I
don't
think I have internalized them to the point where I would write my own
methods that accepted them and worked with them. Has anyone else
been in
the same boat, or do they usually just "click"?

They typically just click :)
 
R

Rick DeNatale

Open classes are best used sparingly. There are problems with them,
of course, in that your code might collide with someone else's code.
The plus though is that all instances of the changed class are
suddenly empowered with new methods you can count on. Some good uses,
in my opinion, are:

* Conversion methods
* DSL

I think that rather than sparingly, the adverb should be carefully.

Open classes are very powerful in situations like building a
framework, (e.g. Rails). Features such as plugins, use formalized
patterns of extending open classes to allow opening classes while
minimizing the potential for collisions.
2. Singleton methods. I really can't think of a particular example
where
I would use this... please help!

Well, technically you use this feature in Ruby anytime you create a
class method. Outside of that, it's another feature best used in
moderation. It does have interesting possibilities though. Here's an
example to try and get you thinking in new directions:
def add_counts(array)
counts = array.inject(Hash.new(0)) { |c, e| c.merge(e => c[e] + 1) }
class << array; self; end.send:)define_method, :counts) do ?> counts
end
end

Right, another is to accomplish what the OP did by adding an instance
to Array in a safer more controlled fashion. Rather than "duck
punching" all now and future instance of Array we can specialize
particular instances.
 
J

James Gray

I think that rather than sparingly, the adverb should be carefully.

Open classes are very powerful in situations like building a
framework, (e.g. Rails). Features such as plugins, use formalized
patterns of extending open classes to allow opening classes while
minimizing the potential for collisions.

In an example in Practical Ruby Projects, the author has to load some
some operating specific code. He feels that open classes are great
for that. He codes up the general interface of the class and then
insert the other methods tailored to the operating system later.

This does seem to come out smoother than having to deal with a bunch
of specific subclasses. The unneeded code is just not added in.

James Edward Gray II
 
R

Robert Dober

In an example in Practical Ruby Projects, the author has to load some
some operating specific code. He feels that open classes are great
for that. He codes up the general interface of the class and then
insert the other methods tailored to the operating system later.

This does seem to come out smoother than having to deal with a bunch
of specific subclasses. The unneeded code is just not added in.
There is almost no Ruby quiz solution I have ever submitted that does
not do that, it feels somehow like, look Ruby I know better than you
do though ;)
 
J

J. Cooper

Hmm... yeah, I think I may literally be too dumb for Ruby. I guess I
just can't get my head around the dynamicness. :(

Thanks for the replies
 
M

Marc Heiler

My personal rule of thumb is, that when something "appears" logical and
straightforward, I use it.

And if i have had bad experience with it in the past, I dont use that
feature.
In the end I use only a subset of Ruby (but it makes me happy because it
is a lot more elegant than any other language I know of).
 

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,774
Messages
2,569,596
Members
45,132
Latest member
TeresaWcq1
Top