tags:

views:

805

answers:

3

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.

+6  A: 

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.

class Foo
  def Foo.bar(my_instance, n)
    my_instance.send(:plus, n)
  end
end
Samuel
+1  A: 

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

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.

rkj
+1  A: 

You could also use instance_eval

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