On Thu, 13 Mar 2003 04:41:17 +0900, (Yukihiro Matsumoto) wrote:

>def statement calls "method_added" _after_ the method definition, so
>you can prevent overriding by removing the method from the class and
>then raising an error from the method_added class method.
>
>Note that this scheme does not prevent removing and replacing in the
>parent class.
>
>							matz.

Thanks so much.  The latter problem is not an issue for me.  Also, in
my app, overriding this base class is a protocol error, so I don't
need to remove the method, just raise an error.  This is what I came
up with in case anyone is interested:

# Prevent a subclass from overriding a superclass' method

class Base
  def Base.meth0; puts '0'; end
  private; def meth1; puts 'A'; end
  protected; def meth2; puts 'B'; end
  public; def meth3; puts 'C'; end
  
  @@base_klass = self
  @@i_methods = instance_methods \
    + protected_instance_methods \
    + private_instance_methods
  @@s_methods = singleton_methods
  
  def Base.prevent_override(id, methods, klass='')
    if methods.include?(id.id2name)
      puts "Override of method #{klass}#{id.id2name} not allowed"
      # raise error, remove method,  whatever
    end
  end
  
  def Base.method_added(id)
    prevent_override(id, @@i_methods)
  end

  def Base.singleton_method_added(id)
    if self == @@base_klass
      prevent_override(id, @@s_methods, self.name+'.')
    end
  end
end

class Sub < Base
  def Base.meth0; puts 'ACK'; end  #--> Error
  def Sub.meth0; puts 'NAK'; end   #--> OK
  def meth4; puts 'D'; end         #--> OK
  def meth1; puts 'B'; end         #--> Error
end


- Jim Davis -