22

The closest I can find is In Ruby, how do I check if method "foo=()" is defined?, but it only works if the method is public, even when inside the class block.

What I want:

class Foo
  private

  def bar
    "bar"
  end

  magic_private_method_defined_test_method :bar #=> true
end

What I've tried:

class Foo
  private

  def bar
    "bar"
  end

  respond_to? :bar #=> false
  #this actually calls respond_to on the class, and so respond_to :superclass gives true
  defined? :bar #=> nil
  instance_methods.include?(:bar) #=> false
  methods.include?(:bar) #=> false
  method_defined?(:bar) #=> false
  def bar
    "redefined!"
  end # redefining doesn't cause an error or anything

  public
  def bar
    "redefined publicly!"
  end #causes no error, behaves no differently whether or not #bar had been defined previously
end
Community
  • 1
  • 1
Shelvacu
  • 4,245
  • 25
  • 44
  • Side note: I was *actually* wondering this and discovered the answer in the course of writing the question. Posted here since I couldn't easily find my answer and so I hope the next bloke will be able to. – Shelvacu Nov 19 '15 at 21:24

2 Answers2

63

Another way is to use :respond_to?, e.g.

self.respond_to?(:bar, true)

Note that the second parameter is important here - it denotes that :respond_to? should look for all scope methods including private methods.

Shelvacu
  • 4,245
  • 25
  • 44
elquimista
  • 2,181
  • 2
  • 23
  • 32
18

You want Module#private_method_defined?.

class Foo
  def do_stuff_if_bar_is_defined
    if self.class.private_method_defined?(:bar)
      do_stuff
    end
  end

  private

  def bar
    "bar"
  end

  private_method_defined? :bar #=> true
end
Foo.private_method_defined? :bar #=> true
Shelvacu
  • 4,245
  • 25
  • 44