Ruby动态“类型转换”使用存储在变量中的类名

时间:2013-09-27 15:37:45

标签: ruby

我想像这样设置一个哈希:

{:a => Float, :b => String}

这样我就可以将它用作针对另一个哈希的“类型转换”过滤器。例如:

def parse_hash(input_hash)
  output = { :a => Float, :b => String }
  input_hash.each do |k,v|
    input_hash[k] = output[k](v)
  end
end

这个想法是,你可以这样做:

Float("123") #=> 123.0

但不幸的是,你做不到:

f = Float
f("123") #=> NoMethodError: undefined method `f' for main:Object

...这意味着我要使用的哈希解析方法不起作用。

所以,如果我在变量中引用了一个类,是否有任何方法可以从那里自动强制将值强制转换为该类?

3 个答案:

答案 0 :(得分:9)

作为一个类的Float和作为方法的Float之间存在细微差别。 Ruby解释器将区分语法级别,它基于您如何使用它。 Float("1.0")是该方法的触发器,Float "1.0"也是如此,但a = Float被解释为类。

您需要专门捕获该方法:

output = {
  a: method(:Float),
  b: method(:String)
}

然后,打电话给它:

output[:a].call('1.7')
# => 1.7

答案 1 :(得分:1)

作为对tadman的回答的补充,这里是所有的Kernel方法,它们是方法名称没有大写的约定的例外:

2.0.0p247 :021 > Kernel.methods.grep /(^[A-Z][a-z]+)+$/
 => [:Integer, :Float, :String, :Array, :Hash, :Rational, :Complex]

更新:修改搜索以适应驼峰情况,同时仍然避免全部大写。排除名称中包含任何非字母字符的方法,无论好坏。另请注意,框架可能会添加到此列表中。两个人都向斯特凡致意。

答案 2 :(得分:0)

您在课程FloatString和方法FloatString之间的混淆是tadman指出的一个问题,但您的代码的另一个问题是

v = ...
哈希循环中的

对哈希没有做任何事情。如果要更改哈希值,则必须执行以下操作:

input_hash[k] = ...