ruby - 在动态命名的对象上调用方法
ruby - calling a method on a dynamically named object
我有一个字符串数组,代表现有的对象名称。
JoesDev = Dev.new
MarksDev = Dev.new
SamsDev = Dev.new
devices=['JoesDev', 'MarksDev', 'SamsDev' ]
我想遍历设备数组,同时对数组中每个项目以其命名的对象调用方法。
即;
JoesDev.method_name
MarksDev.method_name
SamsDev.method_name
我该怎么做?谢谢
好吧,一种方法肯定是使用 eval,一种允许您像执行代码一样执行任意字符串的方法。
因此,在您的示例中:
var_names.each{ |var_name| eval("#{var_name}.some_method") }
不用说,将未经过滤的字符串用作代码是非常危险的,非常糟糕的事情™ 可能会发生!
devices.each{|name| self.class.const_get(name).method_name}
您可以使用 const_get
method from Module
使 Ruby return 具有给定名称的常量。在您的情况下,它将 return Dev
实例用于您给它的任何设备名称。
使用 .each
迭代项目,您的代码可能看起来像
devices.each do |device_name|
device = self.class.const_get(device_name)
device.method_name
end
# Which can be shortened to
devices.each{ |dev| self.class.const_get(dev).method_name }
但是,有更好的方法来实现这类事情。最常见的方法是使用 Hash
。在您的示例中,设备列表可能类似于
devices = {
joe: Dev.new,
mark: Dev.new,
sam: Dev.new
}
然后,遍历设备就像
一样简单
devices.each do |dev|
dev.method_name
end
# Or
devices.each{ |dev| dev.method_name }
额外:如果你想有点花哨,你可以使用block version of Hash::new
使添加新设备变得非常简单。
# Create the hash
devices = Hash.new{ |hash, key| hash[key] = Dev.new }
# Add the devices
devices['joe']
devices['mark']
devices['sam']
这种散列的工作原理与上面所示的完全相同,但如果在散列中找不到给定的键,则会创建一个新条目。这种设计的一个潜在问题是,如果输入错误,您可能会不小心添加新设备。例如
devices['jon'] # This would make a new Dev instance, which may be undesirable.
我有一个字符串数组,代表现有的对象名称。
JoesDev = Dev.new
MarksDev = Dev.new
SamsDev = Dev.new
devices=['JoesDev', 'MarksDev', 'SamsDev' ]
我想遍历设备数组,同时对数组中每个项目以其命名的对象调用方法。
即;
JoesDev.method_name
MarksDev.method_name
SamsDev.method_name
我该怎么做?谢谢
好吧,一种方法肯定是使用 eval,一种允许您像执行代码一样执行任意字符串的方法。
因此,在您的示例中:
var_names.each{ |var_name| eval("#{var_name}.some_method") }
不用说,将未经过滤的字符串用作代码是非常危险的,非常糟糕的事情™ 可能会发生!
devices.each{|name| self.class.const_get(name).method_name}
您可以使用 const_get
method from Module
使 Ruby return 具有给定名称的常量。在您的情况下,它将 return Dev
实例用于您给它的任何设备名称。
使用 .each
迭代项目,您的代码可能看起来像
devices.each do |device_name|
device = self.class.const_get(device_name)
device.method_name
end
# Which can be shortened to
devices.each{ |dev| self.class.const_get(dev).method_name }
但是,有更好的方法来实现这类事情。最常见的方法是使用 Hash
。在您的示例中,设备列表可能类似于
devices = {
joe: Dev.new,
mark: Dev.new,
sam: Dev.new
}
然后,遍历设备就像
一样简单devices.each do |dev|
dev.method_name
end
# Or
devices.each{ |dev| dev.method_name }
额外:如果你想有点花哨,你可以使用block version of Hash::new
使添加新设备变得非常简单。
# Create the hash
devices = Hash.new{ |hash, key| hash[key] = Dev.new }
# Add the devices
devices['joe']
devices['mark']
devices['sam']
这种散列的工作原理与上面所示的完全相同,但如果在散列中找不到给定的键,则会创建一个新条目。这种设计的一个潜在问题是,如果输入错误,您可能会不小心添加新设备。例如
devices['jon'] # This would make a new Dev instance, which may be undesirable.