Forum: Ruby Abstract methods in ruby ?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
1d62a7d62093aa945e67de4119e81dfd?d=identicon&s=25 unknown (Guest)
on 2007-07-12 00:41
(Received via mailing list)
Hi everybody !

How do you implement something like the "abstract" keyword in Java ?
Or: Is there a technique to force a subclass to implement a special
method ?

Kind regards

Dominik
4299e35bacef054df40583da2d51edea?d=identicon&s=25 James Gray (bbazzarrakk)
on 2007-07-12 00:47
(Received via mailing list)
On Jul 11, 2007, at 5:40 PM, cypher.dp@gmail.com wrote:

> How do you implement something like the "abstract" keyword in Java ?
> Or: Is there a technique to force a subclass to implement a special
> method ?

One way is:

class Parent
   def abstract_method
     raise NotImplementedError
   end
end

You may just want to skip this step altogether though, since an
exception toss is the default behavior.

Welcome to the word of dynamic typing.  ;)

James Edward Gray II
1d62a7d62093aa945e67de4119e81dfd?d=identicon&s=25 unknown (Guest)
on 2007-07-12 02:45
(Received via mailing list)
Thanks a lot for the warm welcome, James :)




2007/7/12, James Edward Gray II <james@grayproductions.net>:
703fbc991fd63e0e1db54dca9ea31b53?d=identicon&s=25 Robert Dober (Guest)
on 2007-07-12 14:07
(Received via mailing list)
On 7/12/07, James Edward Gray II <james@grayproductions.net> wrote:
>      raise NotImplementedError
>    end
> end
>
> You may just want to skip this step altogether though, since an
> exception toss is the default behavior.

Hmm, I would say no, you will be caught by #method_missing one day.
It would be interesting why you want to do this?

For documentation purpose? ( Dumbs up !!)

Because you want the feature? (Dumbs down ;)
I have not really yet seen a need for an abstract method in Ruby.
If you are looking for warnings or errors for subclasses not
implementing the abstract method you will be disappointed at Compile
Time [which arguabley does not even exist in 1.8]


If you are happy with the runtime exception (because you do nice code
covering tests ;) James' solution is ideal, anyway you cannot do
better  ( or worse for must of us;) in Ruby.
>
> Welcome to the word of dynamic typing.  ;)

Yes indeed, welcome :)
>
> James Edward Gray II
>
>
Robert
B1b1d33e0655e841d4fd8467359c58d0?d=identicon&s=25 Yossef Mendelssohn (Guest)
on 2007-07-12 14:56
(Received via mailing list)
On Jul 11, 5:44 pm, James Edward Gray II <j...@grayproductions.net>
wrote:
>      raise NotImplementedError
>    end
> end
>
> You may just want to skip this step altogether though, since an
> exception toss is the default behavior.
>
> Welcome to the word of dynamic typing.  ;)
>
> James Edward Gray II

It's true that an exception toss is the default behavior, but it's a
NoMethodError instead of a NotImplementedError and that could be an
important distinction, depending.  And I agree with Robert Dober that
it could get you caught by method_missing one day.

What gets me about NoMethodError is you get that whether there's no
method at all (which follows from the name) or as a result of going
against access control (calling a private or protected method).
4299e35bacef054df40583da2d51edea?d=identicon&s=25 James Gray (bbazzarrakk)
on 2007-07-12 15:34
(Received via mailing list)
On Jul 12, 2007, at 7:05 AM, Robert Dober wrote:

>> class Parent
>>    def abstract_method
>>      raise NotImplementedError
>>    end
>> end
>>
>> You may just want to skip this step altogether though, since an
>> exception toss is the default behavior.
>
> Hmm, I would say no, you will be caught by #method_missing one day.
> It would be interesting why you want to do this?

If someone adds a method_missing() implementation to a child class
that accepts messages it shouldn't, there is a bug in that
implementation and it needs to be fixed.  Your tests are going to
catch that for you.

> For documentation purpose?

That is about the best reason to add the stub, I think.

> If you are looking for warnings or errors for subclasses not
> implementing the abstract method you will be disappointed at Compile
> Time [which arguabley does not even exist in 1.8]

class AbtractClass
   REQUIRED_METHODS = %w[one two three]

   def self.inherited(subclass)
     REQUIRED_METHODS.each do |m|
       raise "An implementation of #{m} is required by #{self.class}" \
         unless subclass.instance_methods.include? m
     end
   end
end

class Broken < AbtractClass
   def one; end
   def two; end
end
# ~> -:7:in `inherited': An implementation of one is required by
Class (RuntimeError)
# ~>   from -:5:in `each'
# ~>   from -:5:in `inherited'
# ~>   from -:12

But don't do that.  ;)

James Edward Gray II
454bd31c811ab511d9c993ec2b3e7d82?d=identicon&s=25 George Malamidis (Guest)
on 2007-07-12 15:55
(Received via mailing list)
Hi,

Not sure if this has been mentioned already, but you might also be
interested in checking out http://rubyforge.org/projects/abstract/

George
703fbc991fd63e0e1db54dca9ea31b53?d=identicon&s=25 Robert Dober (Guest)
on 2007-07-12 16:20
(Received via mailing list)
On 7/12/07, James Edward Gray II <james@grayproductions.net> wrote:
<snip>
>          unless subclass.instance_methods.include? m
> # ~>    from -:5:in `each'
> # ~>    from -:5:in `inherited'
> # ~>    from -:12
>
> But don't do that.  ;)
That does not work as you have intended, it is complaining about #one
missing as a matter of fact:

531/31 > cat subclass.rb && ruby subclass.rb
# vim: sw=2 ts=2 ft=ruby
 class P
    def self.inherited(subclass)
                        puts "P --> #{subclass}"
    end
 end

 class C < P
                puts "in C"
 end
P --> C
in C

Robert
4299e35bacef054df40583da2d51edea?d=identicon&s=25 James Gray (bbazzarrakk)
on 2007-07-12 16:48
(Received via mailing list)
On Jul 12, 2007, at 9:17 AM, Robert Dober wrote:

>>    def self.inherited(subclass)
>>    def two; end
>> end
>> # ~> -:7:in `inherited': An implementation of one is required by
>> Class (RuntimeError)
>> # ~>    from -:5:in `each'
>> # ~>    from -:5:in `inherited'
>> # ~>    from -:12
>>
>> But don't do that.  ;)
> That does not work as you have intended, it is complaining about #one
> missing as a matter of fact:

You are right.  My mistake.

James Edward Gray II
8029153bbcbda4a6844440c93e0c6422?d=identicon&s=25 Thomas Hafner (Guest)
on 2007-07-21 13:01
(Received via mailing list)
cypher.dp@gmail.com wrote/schrieb
<2b4059ff0707111540w6cf25d59q10944fad85bc2dd1@mail.gmail.com>:

> Or: Is there a technique to force a subclass to implement a special method ?

Alternatively try something similiar to the the NVI idiom in C++:

  # interface
  module MyInterface
    def foo(*args, &block)
      do_foo(args, block)
    end
  end

  # special implementation of interface
  class MyClass
    include MyInterface

    private
    def do_foo(args, block)
      # TODO complete implementation
    end
  end

Regards
  Thomas
This topic is locked and can not be replied to.