On 3/12/06, kwatch [email protected] wrote:
Logan,
Oh look, this code already raises an exception, a NoMethodError. Now
I know that to include Enumerable I have to have an each method.
That’s all there is to it.
I think it is very important that the code itself is descriptive. The
following code doesn’t describe that method each() is abstract.
module Enumerable
def map
arr = []
each { |elem| arr << yield(elem) }
arr
end
end
Actually, the method #each is not abstract in Enumerable. It’s a
prerequisite. There’s a difference. In the C++ and Java world, it’s
necessary to define a prerequisite method as an abstract method,
because without a method definition, the compiler goes stupid and can’t
find anything and won’t then compile your code at all. Ruby sees the
call to #each with a block and says “okay, I’ll trust that you’ve
satisified this until I hit it at run time.”
The following code itself describes that method each() is abstract.
It’s more descriptive.
module Enumerable
abstract_method :each
def map
arr = []
each { |elem| arr << yield(elem) }
arr
end
end
Please take care of reading code, as well as writing code. You may
insist that documentation is sufficient to describe that, but
documentation is assistant and code should be prime.
What you’ve got is no better than:
Every method provided in Enumerable requires that the including
class defines an #each method that iterates one item at a time.
module Enumerable
def map
arr = []
each { |elem| arr << yield(elem) }
arr
end
end
Except that it actually adds a little code for what is essentially a
documentation annotation. As I said, it adds little to no value to Ruby
and IMO doesn’t belong in the core.
Oh look, this code already raises an exception, a NoMethodError.
NoMethodError is not proper to abstract method, I think.
I think that it is. It says that there’s no method for what’s being
looked for. Having “abstract_method :each” doesn’t add value to that.
end
def visit_bar; … ; end
‘Visitor’ module may not be necessary when a number of visitor class
is only 1.
But there should be ‘Visitor’ module in the case that many visitor
classes are needed. It’s more descriptive.
Disagree. In Ruby, inclusion of a Module means something. Specifically,
it means that you’re mixing in functionality … not that you’re mixing
in warnings or merely documenting things.
# Items of class Hoge can be visited by classes that know how to
# #visit_foo or #visit_bar.
class Hoge
def visit_foo; ... ; end
def visit_bar; ... ; end
end
# Items of class Fuga can be visited by classes that know how to
# #visit_foo or #visit_bar.
class Fuga
def visit_foo; ... ; end
def visit_bar; ... ; end
end
# Items of class Geji can only be visited by classes that know how
# to #visit_foo.
class Geji
def visit_foo; ... ; end
end
Start thinking like a duck man.
You mean ‘duck typing’? Duck typing is one thing and abstract method
is another.
Not really. As I noted earlier, abstract methods are necessary in
statically typed and linked languages because they’re aggressive in
resolving “facts”, whereas Ruby is lazy and doesn’t try to resolve
things until they’re needed.
Ask yourself what is the purpose of an abstract method.
Then ask yourself if that need is already fufilled in ruby.
Abstract method is useful to realize ‘descriptive code’.
It increases code maintanancability.
Disagree. IME, it does the opposite and reduces the descriptiveness and
usefulness of the code. Stop thinking in C++ – in Ruby, abstract
methods simply aren’t necessary.
Trust me. You won’t find them in Rails, PDF::Writer, or any of a variety
of other large and popular packages.
-austin