Ruby-pass方法(?)作为参数?
在Ruby中,我有一整套从数据库返回信息的方法:州、国家、语言、民族等列表,用于申请表单的选项。我从表单中知道所选ID,并且正在编写从ID中获取名称的方法: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_
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
的单个方法来实现,但它不是那么透明。