Isolate Ruby methods from overriding in subclasses? (e.g. Java private methods)

In Ruby, I would like to get something like this Java example:

class A {        
    private void f() {  System.out.println("Hello world"); }
    public  void g() { f(); }
}
class B extends A {
    public void f() { throw new RuntimeException("bad guy");}
}
public class Try {
    public static void main(String[] args) { new B().g();}
}

This will print "Hello world" in Java, but direct Ruby transcription:

class A   
    def g; f; end 
    private
    def f; puts "Hello world"; end
end
class B < A
    def f; raise "bad guy"; end
end
B.new.g    # want greet

of course, will raise a bad guy - due to differences in the method search method (I understand that the value of 'private' is very different between these languages)

Is there any way to achieve this effect? I don’t really like visibility, in fact, I would prefer all public methods here. My goal is simply to isolate the method in the superclass from overriding in subclasses (which will break other basic methods).

I think if there is a solution that will work with / modules too?

module BaseAPI 
   def f; puts "Hello world"; end
   def g; f; end;
end
module ExtAPI 
  include BaseAPI
  # some magic here to isolate base method :f from the following one?
  def f; raise "bad guy"; end # could actually be something useful, but interfering with base 'g'
end
include ExtAPI
g # want greet

Follow-up observation: this looks like a rare case when something is possible with Java, but not with Ruby: - ​​/

+3
2
class A
  def g
    real_f
  end 
  private
  def f
    real_f
  end
  def real_f
    puts "Hello world"
  end
end
class B < A
  def f
    raise "bad guy"
  end
end
B.new.g    # want hello world

, , . Ruby . AA. , , method_missing() .

class A
  def g
    f
  end 
  def f
    puts "Hello world"
  end
end
class AA
  def initialize
    @x = A.new
  end
  def g
    @x.g
  end
  def f
    @x.f
  end
end
class B < AA
  def f
    raise "bad guy"
  end
end
B.new.g    # want hello world
0
class A;   def g;f;end ; private ;def f;puts "Hello world";end;end
class B < A 

  def self.method_added(name)
    if superclass.method_defined? name  or superclass.private_method_defined? name
      raise "A trial to add a new instance method: #{name}, this is not allowed." 
    end
  end 

  def f;raise "bad guy";end;

end
#=>`method_added': A trial to add a new instance method: f,
#   this is not allowed.(RuntimeError)
-1

Source: https://habr.com/ru/post/1718613/


All Articles