元编程-动态方法

时间:2018-12-27 13:16:24

标签: ruby-on-rails ruby

我在这里有2个版本的计算机课。我看到Computer2比Computer1好得多。两种计算机类都产生相同的结果。 Computer2类与Computer1类有何不同?

class DataSource
  def cpu_info(computer_id)
    "#{computer_id}'s CPU"
  end

  def cpu_price(computer_id)
    12
  end

  def mouse_info(computer_id)
    "#{computer_id}'s mouse"
  end

  def mouse_price(computer_id)
    27
  end

  def monitor_info(computer_id)
    "#{computer_id}'s monitor"
  end

  def monitor_price(computer_id)
    33
  end
end

# Step 1
class Computer1
  def initialize(computer_id, data_source)
    @id = computer_id
    @ds = data_source
  end

  def cpu
    get_info :cpu
  end

  def mouse
    get_info :mouse
  end

  def monitor
    get_info :monitor
  end

  def get_info(component)
    component_info = @ds.send("#{component}_info", @id)
    component_price = @ds.send("#{component}_price", @id)
    data = "The work station #{component_info} is about #{component_price}$"
    return data;
  end
end

computer = Computer1.new(1, DataSource.new)
computer.cpu #The work station 1's CPU is about 12$

# Step 2 - Further simplified
class Computer2
  def initialize(computer_id, data_source)
    @id = computer_id
    @ds = data_source
  end

  def self.get_info(component)
    define_method(component) do
      component_info = @ds.send("#{component}_info", @id)
      component_price = @ds.send("#{component}_price", @id)
      data = "The work station #{component_info} is about #{component_price}$"
      return data;
    end
  end

  get_info :mouse
  get_info :cpu
  get_info :monitor
end

computer = Computer2.new(1, DataSource.new)
computer.cpu #The work station 1's CPU is about 12$

我的问题是,由于Computer2类中没有实例cpu方法,因此下面的方法是可能的

computer = Computer2.new(1, DataSource.new)
computer.cpu

2 个答案:

答案 0 :(得分:1)

在加载类Computer2时,自我调用带有参数get_info的{​​{1}}类方法,该参数随后用于为Computer2实例定义实例方法:cpu

阅读define_method

答案 1 :(得分:1)

在Computer2类中,调用方法:get_info:

cpu

此方法,调用ruby函数:define_method(https://apidock.com/ruby/Module/define_method),在这种情况下,此方法为您的实例创建一个命名函数,在调用get_info :mouse get_info :cpu get_info :monitor 之后,您将获得get_info(:cpu)方法呼叫,并附赠:

.cpu