从Ruby中的类方法调用私有实例方法

时间:2023-01-15 20:20:01

Can I create a private instance method that can be called by a class method?

我可以创建一个可以被类方法调用的私有实例方法吗?

class Foo
  def initialize(n)
    @n = n
  end
  private # or protected?
  def plus(n)
    @n += n
  end
end

class Foo
  def Foo.bar(my_instance, n)
    my_instance.plus(n)
  end
end

a = Foo.new(5)
a.plus(3) # This should not be allowed, but
Foo.bar(a, 3) # I want to allow this

Apologies if this is a pretty elementary question, but I haven't been able to Google my way to a solution.

如果这是一个非常基本的问题,我很抱歉,但我还没能找到解决方案。

3 个解决方案

#1


18  

Using private or protected really don't do that much in Ruby. You can call send on any object and use any method it has.

使用private或protected在Ruby中并不是很有用。您可以对任何对象调用send并使用它拥有的任何方法。

class Foo
  def Foo.bar(my_instance, n)
    my_instance.send(:plus, n)
  end
end

#2


9  

You can do it as Samuel showed, but it is really bypassing the OO checks...

你可以像Samuel说的那样做,但是它确实绕过了OO检查……

In Ruby you can send private methods only on the same object and protected only to objects of the same class. Static methods reside in a meta class, so they are in a different object (and also a different class) - so you cannot do as you would like using either private or protected.

在Ruby中,您只能将私有方法发送到相同的对象上,而只能将受保护的方法发送到相同类的对象上。静态方法驻留在元类中,因此它们位于不同的对象(以及不同的类)中——因此您不能按照您希望的方式使用private或protected。

#3


6  

You could also use instance_eval

您还可以使用instance_eval

class Foo
  def self.bar(my_instance, n)
    my_instance.instance_eval { plus(n) }
  end
end

#1


18  

Using private or protected really don't do that much in Ruby. You can call send on any object and use any method it has.

使用private或protected在Ruby中并不是很有用。您可以对任何对象调用send并使用它拥有的任何方法。

class Foo
  def Foo.bar(my_instance, n)
    my_instance.send(:plus, n)
  end
end

#2


9  

You can do it as Samuel showed, but it is really bypassing the OO checks...

你可以像Samuel说的那样做,但是它确实绕过了OO检查……

In Ruby you can send private methods only on the same object and protected only to objects of the same class. Static methods reside in a meta class, so they are in a different object (and also a different class) - so you cannot do as you would like using either private or protected.

在Ruby中,您只能将私有方法发送到相同的对象上,而只能将受保护的方法发送到相同类的对象上。静态方法驻留在元类中,因此它们位于不同的对象(以及不同的类)中——因此您不能按照您希望的方式使用private或protected。

#3


6  

You could also use instance_eval

您还可以使用instance_eval

class Foo
  def self.bar(my_instance, n)
    my_instance.instance_eval { plus(n) }
  end
end