brauliobo
brauliobo

Reputation: 6315

Ruby's `respond_to?` do not work just after definition?

I have a module that defines a method if it is not already defined. This is the case of ActiveRecord's attributes as theirs getters and setters are not defined as methods.

module B
  def create_say_hello_if_not_exists
    puts respond_to?(:say_hello)
    define_method :say_hello do
      puts 'hello'
    end unless respond_to?(:say_hello)
  end
end

class A
  def say_hello
    puts 'hi'
  end
  puts respond_to?(:say_hello, true)
  extend B
  create_say_hello_if_not_exists
end

A.new.say_hello

The expected result is hi, but ruby prints hello. Why?

Maybe related to Confused about "respond_to?" method

Upvotes: 4

Views: 391

Answers (2)

kuriouscoder
kuriouscoder

Reputation: 5582

The reason why respond_to?(:say_hello) is returning false is due to the fact class A has say_hello as instance method and since you are extending class B the create_say_hello_if_not_exists is declared as class method and it does not find say_hello.

Changing the code to the following would do the trick. I'm declaring say_hello in class A as class method and am calling it in a static manner.


module B
  def create_say_hello_if_not_exists
    puts respond_to?(:say_hello)
    define_method :say_hello do
      puts 'hello'
    end unless respond_to?(:say_hello)
  end
end

class A
  def self.say_hello
    puts 'hi'
  end
  extend B
  create_say_hello_if_not_exists
end

A.say_hello

Upvotes: 0

Schylar
Schylar

Reputation: 774

Try this.

module B
  def create_say_hello_if_not_exists
    puts method_defined?(:say_hello)
    define_method :say_hello do
      puts 'hello'
    end unless method_defined?(:say_hello)
  end
end

class A
  def say_hello
    puts 'hi'
  end
  puts method_defined?( :say_hello )
  extend B
  create_say_hello_if_not_exists
end

A.new.say_hello

Upvotes: 1

Related Questions