Ruby-pass方法(?)作为参数?

Ruby-pass方法(?)作为参数?,ruby,Ruby,在Ruby中,我有一整套从数据库返回信息的方法:州、国家、语言、民族等列表,用于申请表单的选项。我从表单中知道所选ID,并且正在编写从ID中获取名称的方法: def state_name(state_id) Db.states.select{ |s| s['id'] == state_id.to_i }.first['name'] end def country_name(country_id) Db.countries.select{ |c| c['id'] == country_

在Ruby中,我有一整套从数据库返回信息的方法:州、国家、语言、民族等列表,用于申请表单的选项。我从表单中知道所选ID,并且正在编写从ID中获取名称的方法:

def state_name(state_id)
  Db.states.select{ |s| s['id'] == state_id.to_i }.first['name'] 
end

def country_name(country_id)
  Db.countries.select{ |c| c['id'] == country_id.to_i }.first['name'] 
end

等等,有很多。我如何使用一种方法来简化,该方法传入我想要获取名称的项目类型(州、国家等)的名称,而不是一遍又一遍地重复我自己的内容?

您可以通过元编程解决这个问题:

class SomeClass
  def self.define_name_method(thing, plural)
    define_method :"#{thing}_name" do |id|
      Db.send(plural).select {|x| x['id'] == id.to_i }.first['name']
    end
  end

  define_name_method :state, :states
  define_name_method :country, :countries
end

SomeClass.new.state_name(19749387) #=> "Oregon"
或者使用更通用的方法:

class SomeClass
  def thing_name(plural, id)
    Db.send(plural).select{|x| x['id'] == id.to_i }.first['name']
  end
end

SomeClass.new.thing_name(:countries, 1239394) #=> "Estonia"

类似的方法可以工作,使用字符串数组
%w(国家/地区)
并使用
define\u method
.send
Db
上动态创建方法和调用属性

%w(country state language).each do |entity|
  define_method("#{entity}_name") do |id|
    Db.send(entity.pluralize).select{ |o| o['id'] == id.to_i }.first['name']
  end
end
如果不为
使用Rails.pluralize
,则需要“活动\u支持/屈折符”

它动态地创建

def state_name(id)
  Db.states.select{ |o| o['id'] == id.to_i }.first['name'] 
end
依此类推,对于
country\u name
language\u name

,您可以根据作为参数传递的“type name”对当前对象调用其中一个方法:

def name(type, id)
  public_send(:"#{type}_name", id)
end

# Call like this:
name(:state, 1)
或者,您也可以完全放弃定义
{type}\u name
方法,让您的
name
方法在Db对象上调用适当的方法:

def name(type, id)
  Db.public_send(type).select{ |c| c['id'] == id.to_i }.first['name']
end

# Call like this:
name(:countries, 1)

我更喜欢这种方法。通过使用单一方法,可以通过循环收集来提取信息;e、 例如,
arr=[[“国家”,27],,“国家”,341]]。每个带有对象({}{(s,id),h{h[[s,id]]=name(s,id)}
。这仍然可以通过使用
send
的单个方法来实现,但它不是那么透明。