Hi --
I guess my big beef with Ruby is that it is too complex and bloated
with features that often are inconsistent or lack symmetry with each
other. It's too "magical", making it hard to learn exactly how the
language works. From a language design perspective, Ruby really seems
like a mess to me, although with moments of brilliance. Most of the
time, when I'm metaprogramming, I'm guessing and looking at the
output, hoping I got so-and-so quirk correct.
I'd be interested in seeing some of these examples. In my experience,
a great deal of what people find confusing or opaque in Ruby turns out
to be confusing because it is so simple, and because there are so few
exceptions to the rules. I've always been impressed with the
strictness with which Ruby applies a small number of underlying
principles. It's possible that a bit of analysis of some examples
could help you nail some of those.
Okay, there are several little quirks of Ruby that annoy me, but I'll
just a list a couple:
1) When I saw the method! notation for mutation methods, I thought
that was particularly brilliant. But then I noticed that methods are
only postfixed with ! if there was already another method that did the
same thing except on a new copy. It would've been nice of all mutation
methods were postfixed with !. One use case for this would be trapping
all mutation methods of a class for some purpose (e.g. making a read-
only class, or a class that notifies an observer upon mutation).
The ! methods are not specifically mutation methods. See:
http://dablog.rubypal.com/2007/8/15/bang-methods-or-danger-will-rubyist
for an explanation of what they signify (and why it's cool, and why
putting ! on Array#pop and so forth would not be cool).
2) Awkwardness of defining singleton methods. Contrast:
class << obj
def singleton_method
'foo'
end
end
with:
obj.singleton_method = function() {
return 'blah'
}
Of course, YMMV with regards to "elegance".
When writing instance methods, I like to be inside a code definition
block, without regard to whether the class is a singleton class or
not. If you don't, you can always do:
def obj.some_method
but that gets tiresome if you've got a lot of them. class << obj just
puts you in the class block, and then you proceed as you always do
with instance methods. There's really no need for a whole separate
apparatus; the class/object model is already designed to give you the
interface to singleton behavior that you need.
3) There are public/protected/private modifiers for functions, but not
for modules. (Yes, I'm aware that Ruby isn't Java, and that "private"
means "instance-private" not "class-private".)
4) "Scoping" weirdness (or whatever it's called) with modules and
classes.
class A
class << self
attr_accessor :x
def foo
@x = 20
end
end
end
A.foo
p A.x
B = Class.new
B.instance_eval do
attr_accessor :x
def foo
@x = 40
end
end
B.foo
p B.x # error because self within B.instance_eval is still B, not the
singleton thingamajig. Yet by some magic, |def foo| makes a singleton
method.
It's by decree. It's extremely rare to use def inside a code block, so
the idea, as I understand it, is that this is a way to introduce the
ability to do the almost only imagineable such scenario: namely,
creating a singleton method. The other imagineable similar scenario
is represented by class_eval (aka module_eval).
It's also related to the fact that def is a keyword, not a method. In
your example, attr_accessor is simply a method call without an
explicit receiver, which is always sent to "self" (B, in this case).
There's no complexity there. def, however, doesn't have a receiver;
it's a different kind of construct. So decisions always have to be
made about what its effect will be in a given context. Its treatment
in instance_eval is definitely special-cased, but if it weren't (if
def just created an outer-level method, as it would in a
non-special-cased code block), it would never be used (just as def
never is in normal code blocks).
So it's just a bit of quasi-vacant semantic space with a possible
use-scenario, and it got engineered accordingly.
So there's really another type of "scope" or whatever it's called
here: module vs. instance. And I have to remember not to trip up on
it.
In general you have to remember not to trip up on all the idioms of
any language It sounds like you're disgruntled about Ruby
specifically because you're finding things that you have to learn, and
that you can't just slide into based on what you've done in other
languages. That's correct: Ruby really is its own language, and you do
have to learn its idioms and toolsets.
I would second what Ara said, namely that it would be interesting to
see some actual things you're trying to do, and points at which you
feel that Ruby's scoping rules and so forth are stopping you.
David
···
On Sun, 2 Nov 2008, Yuh-Ruey Chen wrote:
On Nov 1, 7:26 am, "David A. Black" <dbl...@rubypal.com> wrote:
--
Rails training from David A. Black and Ruby Power and Light:
Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL
Advancing with Rails January 19-22 Fort Lauderdale, FL *
* Co-taught with Patrick Ewing!
See http://www.rubypal.com for details and updates!