-1

Excuse me for my example; I am trying to develop an independent example to present my requirement, it may appear too contrived:

class Animal
  NAME = 'no name'

  %w(bark walk).each do |action|
    define_method(action) do
      NAME + ' ' + action
    end
  end
end

class Pig < Animal
  NAME = 'piggie'
end

Animal.new.walk # => "no name walk"
Pig.new.walk # => "no name walk"

The last line is expected to return "piggie walk", but it doesn't. Why does that happen and how to make it use the constant defined in Pig?

D-side
  • 9,150
  • 3
  • 28
  • 44
Jikku Jose
  • 18,306
  • 11
  • 41
  • 61

2 Answers2

1

Try something like this

class Animal
  def initialize
    @name ||= "no name"
  end 

  %w(bark walk).each do |action|
    define_method(action) do
      "#{@name} #{action}"
    end 
  end 
end

class Pig < Animal
  def initialize
    @name = 'piggie'
  end 
end

Animal.new.walk # => "no name walk"
Pig.new.walk
Horacio
  • 2,865
  • 1
  • 14
  • 24
0

you need to add define_method in the subclass as well. because what happens it seach walk method in pig class, could not find it and checked super class. now super class has its own constant NAME and it will use that. try this

class Animal
  NAME = 'no name'
 %w(bark walk).each do |action|
    define_method(action) do
      NAME + ' ' + action
    end
  end
end

class Pig < Animal
  NAME = 'piggie'
 %w(bark walk).each do |action|
    define_method(action) do
      NAME + ' ' + action
    end
  end
end

Animal.new.walk
Pig.new.walk

if you dont want bark method simply override walk method rather both.

Athar
  • 3,258
  • 1
  • 11
  • 16