[RCR] abstract method in Ruby

The question is, why use either of those methods? Why not just note
in your documentation that those four functions must be defined? The
user is going to have to read the documentation anyway, in order to
understand what those four abstract methods are for. A
"NoMethodError" conveys the same information as a
"NotImplementedError", in this case.

And this is arguably an abuse of NotImplementedError. The usual
semantics of NotImplementedError are to indicate that the method is
either a) not yet implemented by a library; or b) is not supported on
the current platform. Whereas in the example above it is being used
to indicate that a precondition was not met.

I see that you're trying to make your code more declarative and more
explicit about it's semantics. But seeing 'abstract_method
:will_process_holding' doesn't tell me anything more than getting a
"NoMethodError: will_process_holding". Both of them just tell me I'm
going to have to go look at the documentation to learn what the heck
#will_process_holding is supposed to do.

If you really want to add useful semantic information, then put in
more specific error information where the "abstract" method is
*called*. E.g.:

    def frobnicate(duck)
        duck.quack() rescue NoMethodError raise("Ducks must quack in
order to be frobnicated. See documentation.")
    end

If you want to get fancy and declarative and proactive about it, you
could make a #precondition method:

    def frobnicate(duck)
        precondition("Ducks must quack in order to be frobnicated"){
duck.respond_to? :quack}
    ...
    end

I believe there are some libraries out there that assist in doing this
kind of "strict duck typing".

As a bonus, you are keeping your preconditions close to the code that
actually depends on them, which reduces the chances that they will get
out of sync with your code, and give the user false information.

~Avdi

···

On 3/13/06, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> wrote:

i disagree strongly here. check out these two snippets that i am working on
as we speak:

     def will_process_holding *a, &b
       raise NotImplementedError
     end
     def process_holding *a, &b
       raise NotImplementedError
     end
     def will_process_incoming(*a, &b)
       raise NotImplementedError
     end
     def process_incoming(*a, &b)
       raise NotImplementedError
     end

vs

     abstract_method "will_process_holding"
     abstract_method "process_holding"
     abstract_method "will_process_incoming"
     abstract_method "process_incoming"

I still prefer the "full on type ducking" with a readable comment in the
file. As for the exception that occurs once a month, I get the same
thing in statically compiled language! Sure I am guaranteed that the
method exists due to my compiler bulking at the ommission of my method
definition but since it will only get exercized once a month, I probably
won't see the error till the runtime hits it anyway. (and yes, I have
had yearly bugs pop up on new years day..) The answer is proper test
cases that detect these things early. A compiler making sure your
method exists is not a proper test of the monthly condition that may
occur.

As an aside, I should state that all my Ruby is on peripheral projects
assisting my main enterprise development project. The complexity of my
Ruby projects has not reached 10k LoC so I should make that caveat
clear. :slight_smile:

ilan

unknown wrote:

···

i disagree strongly here. check out these two snippets that i am
working on
as we speak:

     def will_process_holding *a, &b
       raise NotImplementedError
     end
     def process_holding *a, &b
       raise NotImplementedError
     end
     def will_process_incoming(*a, &b)
       raise NotImplementedError
     end
     def process_incoming(*a, &b)
       raise NotImplementedError
     end

vs

     abstract_method "will_process_holding"
     abstract_method "process_holding"
     abstract_method "will_process_incoming"
     abstract_method "process_incoming"

--
Posted via http://www.ruby-forum.com/\.

...

i think it'd be great of rdoc understood and abstract_method hook
just like it now supports the 'attr_XXX' hooks but, even without
that, i'll take any hint i can get in code like this.

Rdoc does! Just use the -A option:

rdoc -A abstract_method=ABSTRACT

or something like that. Change ABSTRACT to be something you like that will tag the attr the the rdoc output.

rdoc -h | grep -A 5 "accessor"
       --accessor, -A accessorname[,..]
                 comma separated list of additional class methods
                 that should be treated like 'attr_reader' and
                 friends. Option may be repeated. Each accessorname
                 may have '=text' appended, in which case that text
                 appears where the r/w/rw appears for normal accessors.
...

···

ara.t.howard@noaa.gov wrote:

--
        vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

*snip*

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.

I still think that kwatch was on to something. It does do more than merely document that the method should be implemented. It describes intention, and provides a uniform and programatic means of doing so. As well as filling in the default function, it could perhaps be used to fill in rdoc generated documentation such that you get a warning about all methods that implementations must provide. Rather than every class that has abstract methods needing to write that documentation and maintain it, it needs to be done once. It's DRYer. I'm sure there are other uses it could be put to, such as interfacing with a static checker if you wanted to build one.

:slight_smile: I'm not saying that I'd necessarily use it either, but I think the idea has merit. It sounds like he's not been put off anyway. If it turns out to be useful over a period of use, and is adopted by some other users, then that's all good and splendid. It's good that people are playing with different ideas that could be useful - it saves me needing to.

···

On 12 Mar 2006, at 20:48, Austin Ziegler wrote:

how about something very simple? i use this in my own code

   class Module
     def abstract_method m
       define_method(m){|*a| raise NotImplementedError}
     end
   end

   module Interface
     abstract_method "foo"
     abstract_method "bar"
   end

   class C
     include Interface
   end

it's quite nice for the rdocs.

regards.

-a

···

On Mon, 13 Mar 2006, Yukihiro Matsumoto wrote:

Hi,

In message "Re: [RCR] abstract method in Ruby" > on Sun, 12 Mar 2006 16:38:44 +0900, "kwatch" <kwa@kuwata-lab.com> writes:

>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

I'm afraid that it doesn't work for some cases, for example:

class Base
   def each
     ...
   end
end

class Derived < Base
   include Enumerable
   ...
end

The abstract "each" method defined in Enumerable overrides the "each"
in the Base class. I'm not against the idea of abstract (or deferred)
method, but sometimes it's not that simple.

--
share your knowledge. it's a way to achieve immortality.
- h.h. the 14th dali lama

Logan Capaldo wrote:

Now if you want to have an argument about static vs. dynamic typing
that's one thing.

I have no intention to argue about dynamic vs. static.
My opinion is that the concept 'abstract method' is useful
in both dynamic and static language.
Static language may have much merits of abstract method
than dynamic language, but the concept of abstract method
give merits to dynamic language, too.

You say that it's important that code be
descriptive. You also say that documentation is insufficient. I
disagree, and say no code is possibly descriptive enough. Whether
attempting to call a method
that relies on an "abstract" method raises a NoMethodError or a
NotImplementedError the result is the same. The programmer must go
read the documentation (or possibly the calling code) to figure out
what was expected of him.

What you say is right. I agree with your opinion.
My point is that program code should be descriptive and
it should be prime documentation than comment or api doc.
Abstract method helps this.

Basically, I feel abstract methods are a primarily feature of static
typing and help ensure the correctness of your code. But they are a
typing feature and the error message you get from them isn't any more
descriptive than "function max expected int, got string"

I separate 'abstract method' and 'typing'. They are different thing, I
think.
I have no intention to bring strong typing into Ruby.
The merits of abstract method is not only typing.
Please take account of reading code, as well as writing or executing
code.
Descriptive code help those who reading the program code.

Tangentially related to this, I find your Visitor example a little
weak, since your Visitor module provides no methods of its own.
Modules are not Java interfaces, and the only reason to write
"include Visitor" in your code is to say
# this class implements the methods required to visit other objects

Hmm, how about the template-method pattern?

  module Template
    def setup
      # default: nothing
    end

    def teardown
      # default: nothing
    end

    abstract_method :main

    def execute
      setup()
      main()
      teardown()
    end
  end

  def Foo
    include Template

    def main
      # do something
    end

    def setup
      # ...
    end
  end

  obj = Foo.new
  obj.execute

I think you've turned the idea of descriptive code into a degenerate
case of ALL this code does is describe. It has no functional purpose.
It's like using no-ops to spell out documentation in morse-code :slight_smile:
(admittedly, that analogy is a bit ridiculous).

Again, please take account of 'readability' of program code.
Higher readability brings higher maintainancability and lower cost.
The aim of abstract method is not to provide concrete functionality.

···

--
regards,
kwatch

Okay, Ara. Why do these methods need to be abstract and specifically have
code around them? IMO, the *same* question should be asked of tsort.rb. I
think that, in both cases, the answer is the same: they don't.

Adding a definition for an "abstract_method" really doesn't add *anything*
to the readability of the code that a well-written comment (which *is* read
by rdoc without modification) doesn't provide.

you are perfectly correct. however, i think we all know that there is a lot
of code, especially in-house, where the docs are pretty thin. in my case
keeping 30,000 lines of ruby documented makes no sense since

   - i'm the only developer

   - we do research and the code changes daily

   - it's less work to use long variable names and abstract code at every
     possible opportunity into stand-alone libs than to write docs.

it just makes my life easier to do things like (all real examples)

   native_int_attribute 'samples'

   xdr_long_attribute 'grid_size'

   $LOAD_PATH << "nrtlib" # vs $:

   abort "#{ $PROGRAM_NAME } parse failure" # vs $0

   hash_of_subscriber_to_prefixes = {}

   abstract_method 'foo'

   required_argument 'dirname'

   option '--verbose', '-v'

in otherwords, to make the code slightly more verbose, self describing, editor
searchable (this is huge ihmho), and clear to someone new taking over the
project because there aint' any docs.

also, i'd maintain encoding sematics into docs is more difficult that it
sounds. if it weren't the entire stdlib would have great docs - lord knows
there has been enough time and man power available. but the truth is in the
puddin - people (myself included) don't do it (enough).

I'm not sure. As I said earlier, PDF::Writer doesn't use them. In
development versions of PDF::Writer, things like that have appeared -- and
promptly been removed because they add clutter, not clarity.

trust me - i with you. sometimes. most of my libs take that approach too.
but sometimes it's nice to be extra clear.

the thing is, having 'abstract_method' does not prevent one from using your
approach - it's simply another arrow in the quiver.

I ask, instead, how old tsort.rb is -- and that will generally indicate why
it has defined abstract methods.

sure. but it's in the stdlib as is alot of old code where often the code is
the only correct/detailed documentation. i don't even use ri or rdoc anymore
- i prefer to simply do something like

   vim -o webrick.rb webrick/*

and peek around. it would be great to then do

   /abstract_method

just as i know often do

   /attr

or

   /def <<

etc.

Ara, this ignores the examples I gave early on:

# All clients of this module must implement #each with no parameters.
module Enum
   def map
     arr =
     each { |elem| arr << yield(elem) }
     arr
   end
end

I have just made #each an abstract method without adding any code at
all.

oh i know, and i'd never use 'abstract_method' here - but what if the number
of 'virtual abstract methods' exceeded fifty?

And I disagree that it makes it easier to read, Ara. I don't write
10,000 line programs,

(OT: me neither btw - but all the libs/progs together approach 30k in my
latest system - i think the largest __file__ is only about 1000 lines. fyi)

but PDF::Writer is 5,000 lines. Certain items, especially in current
development versions, could *easily* have been declared as "abstract" (and
would have to had been in static languages) but aren't necessary to do such
in Ruby.

I really don't think that there's need for this in the core. I think
that the use of it is a crutch; with the programs you have to write,
Ara, that might be necessary. (I've used similar crutches in some
versions of PDF::Writer experiments.)

you may be right here - perhaps a lib only. still, one could make almost
every argument against 'attr' and co. you've made against 'abstract_method'.
both are unnecessary simple convenience solutions for simple problems. still,
unless a more grandiose vision of abstract methods/interfaces is in the plans
- what would it hurt?

kind regards.

-a

···

On Tue, 14 Mar 2006, Austin Ziegler wrote:
--
share your knowledge. it's a way to achieve immortality.
- h.h. the 14th dali lama

It fails in the very way matz indicated.

class Module
  def abstract_method m
    define_method(m){|*a| raise NotImplementedError}
  end
end

module Interface
  abstract_method :foo
  def bar; foo end
end

class C
  def foo; "C#foo" end
end

class D < C
  include Interface
end

D.new.bar
# ~> -:3:in `foo': NotImplementedError (NotImplementedError)
# ~> from -:9:in `bar'
# ~> from -:20

···

On Mon, Mar 13, 2006 at 09:16:30AM +0900, ara.t.howard@noaa.gov wrote:

On Mon, 13 Mar 2006, Yukihiro Matsumoto wrote:
>The abstract "each" method defined in Enumerable overrides the "each"
>in the Base class. I'm not against the idea of abstract (or deferred)
>method, but sometimes it's not that simple.

how about something very simple? i use this in my own code

  class Module
    def abstract_method m
      define_method(m){|*a| raise NotImplementedError}
    end
  end

  module Interface
    abstract_method "foo"
    abstract_method "bar"
  end

  class C
    include Interface
  end

--
Mauricio Fernandez - http://eigenclass.org - singular Ruby

careful - ruby is strongly typed. what it is not is statically typed.

   ruby typing => strong and dynamic

just wanted to point this out because the issue really seems to confuse
people.

i'm all for your RCR btw...

regards.

-a

···

On Mon, 13 Mar 2006, kwatch wrote:

I separate 'abstract method' and 'typing'. They are different thing, I
think. I have no intention to bring strong typing into Ruby. The merits of
abstract method is not only typing. Please take account of reading code, as
well as writing or executing code. Descriptive code help those who reading
the program code.

--
share your knowledge. it's a way to achieve immortality.
- h.h. the 14th dali lama

I don't believe it is any more descriptive than the current situation. I think that whenever possible, you are right code should be self-describing, but I don't think abstract methods are self-describing.

I think that in ruby this already _is_ self describing:

module Enumerable
   ...
   def map(&block)
         results =
         each { |x| results << block.call(x) }
          results
   end
end

Looking at this a programmer using this api will say, ok I need to provide an each method,
and it needs to take a block. That's what the code tells him. If he doesn't read the code, and attempts to use Enumerable, he will get an exception. This exception will tell him what method his object doesn't implement that enumerable relies upon. This exception may be a NoMethodError, or a NotImplementedError. Either way though he has to go back to the code or docs to see what is expected. Implementing an each that doesn't take a block or an each that takes more or less arguments than its expected too is just as bad as or worse than no each at all. I digress though, because what it really comes down to is that your abstract_method should be a comment or an rdoc directive. It really, really should. There is no reason to write code that does effectively nothing. Your abstract method (irrespective of abstract methods in other languages) is a documentation tool, and that's where it should be implemented. You say "consider readability", so do I. What is more readable, a comment telling me I need to have an each method to include Enumerable, possibly even explaining why, or a a call to a class method named abstract _method? Now admittedly I can guess what that means, but I still have to find out to be sure. Especially since it looks like its doing something. A comment can be just as short as your method call, doesn't introduce any new code and it IS part of the code, unless you read your code with all the comments stripped out. You keep saying code should be descriptive, I don't believe this adds to the descriptiveness. Which is why I would not want this in the core ruby. It doesn't add anything.

···

On Mar 12, 2006, at 10:08 PM, kwatch wrote:

What you say is right. I agree with your opinion.
My point is that program code should be descriptive and
it should be prime documentation than comment or api doc.
Abstract method helps this.

What's the big difference between

# abstract method foo

and

abstract_method :foo ?

This is what's boggling my mind. It's not writing some documentation, its writing it in the same place you'd call your abstract_method method anyway. And you can still search for it within vim or whatever. I don't know enough about your particular case for "native_int_atrribute" but tyou're probably talkign to some library that expects an int and that method probably does some checking on assignment, which is fine. That makes sense. What I'm suggesting is that although a program should explode immediately when there's a problem, it also shouldn't explode when there isn't one. If I never call map, each will never be called, so its ok if I don't implement it. Then on the day I do call it, and run it for the first time, it expldoes right there, when I'm calling each. I know immediately what change I _just_ made caused it to explode. OTOH if I mixin Enumerable w/o an each, and each is an "abstract_method" it breaks whether I use it or not. But when everbody starts using abstract methods, all of a sudden I'm back in the land of compile-fix, compile-fix. Cause that error is gonna happen right away, so I have to deal with that immediate error. Then I can run it again to make sure it works, but now the error happens again, compile-fix ad infinitum.

···

On Mar 13, 2006, at 2:21 PM, ara.t.howard@noaa.gov wrote:

you are perfectly correct. however, i think we all know that there is a lot
of code, especially in-house, where the docs are pretty thin. in my case
keeping 30,000 lines of ruby documented makes no sense since

  - i'm the only developer

  - we do research and the code changes daily

  - it's less work to use long variable names and abstract code at every
    possible opportunity into stand-alone libs than to write docs.

indeed. hmmm:

   harp:~ > cat a.rb
   class Module
     def abstract_method m
       define_method(m){|*a| super rescue raise NotImplementedError}
     end
   end
   module Interface
     abstract_method :foo
     def bar; foo end
   end
   class C
     def foo; "C#foo" end
   end
   class D < C
     include Interface
   end
   p D::new.foo

   harp:~ > ruby a.rb
   "C#foo"

though i only now thought of that - so there's probably another failing case...

probably don't want a blanket rescue for one...

regards.

-a

···

On Mon, 13 Mar 2006, Mauricio Fernandez wrote:

It fails in the very way matz indicated.

class Module
def abstract_method m
   define_method(m){|*a| raise NotImplementedError}
end
end

module Interface
abstract_method :foo
def bar; foo end
end

class C
def foo; "C#foo" end
end

class D < C
include Interface
end

D.new.bar
# ~> -:3:in `foo': NotImplementedError (NotImplementedError)
# ~> from -:9:in `bar'
# ~> from -:20

--
share your knowledge. it's a way to achieve immortality.
- h.h. the 14th dali lama

Erik Veenstra wrote:

You can't call them *abstract* methods if you implement them
like this.
In Java, the presence of methods is checked at compiletime, if
they are defined "abstract". Your solution only checks the
presence of these methods at runtime, which is already checked
by Ruby itself.

I don't want the just same as Java's abstract method.
I know Ruby is dynamic language.
I don't intend to bring checking at compiletime nor strictly typing.

Yukihiro Matsumoto wrote:

I'm afraid that it doesn't work for some cases, for example:

  class Base
    def each
      ...
    end
  end

  class Derived < Base
    include Enumerable
    ...
  end

The abstract "each" method defined in Enumerable overrides the "each"
in the Base class. I'm not against the idea of abstract (or deferred)
method, but sometimes it's not that simple.

Oh, I didn't realized that.
How about this?

  class Derived < Base
    alias each_orig each
    include Enumerable
    alias each each_orig
    ...
  end

It's not simple....orz

···

ara.t.how...@noaa.gov wrote:

  class Module
    def abstract_method m
      define_method(m){|*a| super rescue raise NotImplementedError}
    end
  end

It seems to be a good solution.
I'll consider and examine this idea.
Thanks ara.

--
regards,
kwatch

Umm, except, no. Maybe if we used Erik's "allocation-time checking"
approach, but not with kwatch's NotImplementedError approach. If you
mixin Enumerable, but then never call map/inject/collect/etc., you'll
never get the NotImplementedError exception, just as you never got the
NoMethodError exception. As far as *behavior*, timing/severity of the
failure is exactly the same -- you get an exception when the library
tries to use the method you should have defined.

The value of Erik's approach (which, as Pit and Matz pointed out,
needs refining) is in self-documentation and explicit error messages.
Obviously, you and Ara don't agree on how much that self-documentation
is worth. I'm not sure either; you both make good arguments. This is
the reason why I also vote against it being in the core.

However, I *highly* value the more descriptive exception. I'll take an
exception that tells me "If you want to extend Enumerable, you need to
provide an 'each' method" over "NoMethodError: each" any day. Sure, I
have to go back to the documentation and see what that each method
should do, but I know more precisely why things are failing. You may
disagree, and that's fine. I'm just staing my opinion as to why I
think it will be a valuable non-core library.

Jacob Fugal

···

On 3/13/06, Logan Capaldo <logancapaldo@gmail.com> wrote:

... What I'm suggesting is
that although a program should explode immediately when there's a
problem, it also shouldn't explode when there isn't one. If I never
call map, each will never be called, so its ok if I don't implement
it. Then on the day I do call it, and run it for the first time, it
expldoes right there, when I'm calling each. I know immediately what
change I _just_ made caused it to explode. OTOH if I mixin Enumerable
w/o an each, and each is an "abstract_method" it breaks whether I use
it or not. But when everbody starts using abstract methods, all of a
sudden I'm back in the land of compile-fix, compile-fix. Cause that
error is gonna happen right away, so I have to deal with that
immediate error. Then I can run it again to make sure it works, but
now the error happens again, compile-fix ad infinitum.

sure. this one's a bit more robust since it doesn't mask errors:

     harp:~ > cat a.rb
     class Module
       def abstract_method m
         define_method(m) do |*a|
           begin; super; rescue NoMethodError; raise NotImplementedError, m; end
         end
       end
     end
     module Interface
       abstract_method :foo
       def bar; foo end
     end
     class C
       def foo; "C#foo" end
     end
     class D < C
       include Interface
     end
     p D::new.foo

     harp:~ > ruby a.rb
     "C#foo"

regards.

-a

···

On Mon, 13 Mar 2006, kwatch wrote:

ara.t.how...@noaa.gov wrote:

  class Module
    def abstract_method m
      define_method(m){|*a| super rescue raise NotImplementedError}
    end
  end

It seems to be a good solution.
I'll consider and examine this idea.
Thanks ara.

--
share your knowledge. it's a way to achieve immortality.
- h.h. the 14th dali lama

Hi,

···

In message "Re: [RCR] abstract method in Ruby" on Mon, 13 Mar 2006 12:33:45 +0900, "kwatch" <kwa@kuwata-lab.com> writes:

  class Base
    def each
      ...
    end
  end

  class Derived < Base
    include Enumerable
    ...
  end

The abstract "each" method defined in Enumerable overrides the "each"
in the Base class. I'm not against the idea of abstract (or deferred)
method, but sometimes it's not that simple.

Oh, I didn't realized that.

It's caused by mix-in, a kind of multiple inheritance. The above is
rather artificial case, so that it does not cause troubles on most of
the cases, but if we want to add abstract method in the core, I think
we need to care about such cases as well.

              matz.

Hi,

At Mon, 13 Mar 2006 13:10:45 +0900,
ara.t.howard@noaa.gov wrote in [ruby-talk:183841]:

     harp:~ > cat a.rb
     class Module
       def abstract_method m
         define_method(m) do |*a|
           begin; super; rescue NoMethodError; raise NotImplementedError, m; end

This hides NoMethodError within the super method too.

Instead:

      defined?(super) or raise NotImplementedError, m
      super

···

--
Nobu Nakada

Quoting ara.t.howard@noaa.gov:

sure. this one's a bit more robust since it doesn't mask errors:

       def abstract_method m
         define_method(m) do |*a|
           begin; super; rescue NoMethodError; raise
NotImplementedError, m; end
         end
       end

Hmm, what about cases where the super exists, but calls something
which itself raises a NoMethodError?

-mental

hmmm - but that (both actually) fails here:

     harp:~ > cat a.rb
     class Module
       def abstract_method m
         define_method(m) do |*a|
           defined?(super) ? super : raise(NotImplementedError, m)
         end
       end
     end

     class A
       def foo; 42; end
     end
     class B < A
       abstract_method "foo"
     end

     p B::new.foo

     harp:~ > ruby a.rb
     42

what about this fix?

     harp:~ > cat a.rb
     class Module
       def abstract_method m
         already_respond_to_m = instance_method(m) rescue nil

         define_method(m) do |*a|
           if already_respond_to_m
             raise(NotImplementedError, m)
           else
             defined?(super) ? super : raise(NotImplementedError, m)
           end
         end

       end
     end

     class A
       def foo; 42; end
     end
     class B < A
       abstract_method "foo"
     end

     p B::new.foo

     harp:~ > ruby a.rb
     b.rb:7:in `foo': foo (NotImplementedError)
             from b.rb:23

thoughts?

-a

···

On Mon, 13 Mar 2006 nobu@ruby-lang.org wrote:

Hi,

At Mon, 13 Mar 2006 13:10:45 +0900,
ara.t.howard@noaa.gov wrote in [ruby-talk:183841]:

     harp:~ > cat a.rb
     class Module
       def abstract_method m
         define_method(m) do |*a|
           begin; super; rescue NoMethodError; raise NotImplementedError, m; end

This hides NoMethodError within the super method too.

Instead:

     defined?(super) or raise NotImplementedError, m
     super

--
share your knowledge. it's a way to achieve immortality.
- h.h. the 14th dali lama

ara.t.howard@noaa.gov schrieb:

(... implementing Module#abstract_method ...)

All those implementations which actually create dummy methods prohibit implementing an abstract method using method_missing.

Regards,
Pit