【发布时间】:2025-12-04 09:35:01
【问题描述】:
假设我希望 String 的某些实例与其他“正常”实例的行为不同 - 例如取消“upcase”方法的效果。我执行以下操作:
class String
def foo
def self.upcase
self
end
self
end
end
它似乎工作正常,我需要它的方式:
puts "bar".upcase #=> "BAR"
puts "bar".foo.upcase #=> "bar"
但是,一旦我使用被欺骗的 String 实例作为 Hash 的键,我的行为就开始看起来很奇怪:
puts ({"bar".foo => "code"}).keys.first.upcase #=> "BAR", not "bar"!
... 相当于忽略了 foo 方法,将 String 的原始实例作为 key。
任何人都可以看到这里发生了什么?非常感谢!
【问题讨论】:
-
我有一种强烈的感觉,对于您的实际问题,无论是什么,都有比这更好的解决方案。为什么你不希望这个字符串响应大写?
-
我的问题可能足够具体,需要此解决方案,因为我使用 Ruby 生成 Javascript。在这种特殊情况下,我需要将 Hash 的键从下划线转换为驼峰式,以便生成的 JS 代码读起来自然。但是,在某些情况下,我只想让某些键完全按照我指定的方式保留,因此我添加了这个“修饰符”函数(上例中的“foo”,下例中的“preserve”),以取消转换,希望能够做到这一点: ({"converted_key" => 1, "passed_as_is".preserve => 1}).to_js #=> {"convertedKey" => 1, "passed_as_is" => 1}。我希望这是有道理的。
-
嗯。因此,也许您可以将 Ruby 键的哈希值保留为 Javascript 键?然后,您会将您的特殊情况逻辑放入此哈希的创建中,因此 "this_one" => "ThisOne" 但 "this_special_one" => "this_special_one"。
标签: ruby hash metaprogramming