我写了一些使用“动态哈希”的代码来返回键的值,其中值是计算的。我在 irb (RUBY_VERSION 2.3.3)下进行了测试,一切看起来都不错。下面是一个展示这个想法的简单例子。
PROPS = Hash.new { |hash,key| key.to_s + "!" }
"Foo: %{foo} Bar: %{bar}" % PROPS # => "Foo: foo! Bar: bar!"
PROPS[:xyzzy] # => "xyzzy!"
但是然后将我的代码部署到它使用的环境(建模工具Sketchup的插件),这显然有Ruby 2.2.4上面的字符串格式化示例产生KeyError:key {foo} not found。
PROPS = Hash.new { |hash,key| key.to_s + "!" }
"Foo: %{foo} Bar: %{bar}" % PROPS # KeyError: key{foo} not found
PROPS[:xyzzy] # => "xyzzy!"
但是使用任何键访问哈希都可以正常工作......在http://ruby-doc.org/core-2.2.4/Kernel.html#method-i-sprintf处读取并没有提供太多指定哈希默认值不会按预期运行的方式。
显然我可以做不同的事情,比如发明我自己的替换函数和变量语法。顺便说一下,显然传递给“%”或sprintf的“哈希”实际上必须是哈希对象,这违反了Ruby所谓的鸭子类型灵活性。
答案 0 :(得分:1)
我可以确认它在Ruby 2.1.5中不起作用。
我将提供一些提示,告诉你如何找出要定义的ruby代码,以便在不从MRI读取C或Ruby代码的情况下获取内容。
我知道,这不是一个完整的答案,但文字太长,无法发表评论。
以下是irb会话
>> detector = Object.new
=> #<Object:0x00000002257900>
>> def detector.method_missing m
>> puts m.to_s
>> end
=> :method_missing
>> "Foo: %{fnoo} Bar: %{bar}" % detector
to_ary
to_hash
ArgumentError: one hash required
from (irb):37:in `%'
from (irb):37
from /home/felix/.rvm/rubies/ruby-2.1.5/bin/irb:11:in `<main>'
这告诉我们在插值方法中调用了我们的虚拟“探测器”对象(to_hash
)没有实现的精确;通过其他测试,我知道如果给定对象是哈希,也会调用to_ary,所以我们可以忽略那个)。
然而,它并没有告诉我们是否已经有detector.class
或detector is_a Hash?
等。被叫了。
现在我等待downvotes;)
顺便说一句,如果你想通过C潜水 - 而且我开始相信这可能是需要的 - 你可以在这里开始挖掘:https://github.com/ruby/ruby/blob/6d728bdae9de565ad9d0b2fee2d4c2a33c6f4eac/sprintf.c#L579(在ruby 2.1上或多或少“sprintf”)