Ruby语法:x('foo',y:'bar',z:'baz')与x('foo',@ yz)不同?

时间:2011-10-03 21:25:00

标签: ruby-on-rails ruby internationalization

给出一种方法:

def x(*a)

可以像这样调用它:

 x('foo', y: 'bar', z: 'baz')

与以下不同:

@yz = { y: 'bar', z: 'baz' }
x('foo', @yz)

我问,因为我找到了I18n.translate方法,定义为:

def translate(*args)
  options  = args.last.is_a?(Hash) ? args.pop : {}
  key      = args.shift
  backend  = config.backend
  locale   = options.delete(:locale) || config.locale
  handling = options.delete(:throw) && :throw || options.delete(:raise) && :raise # TODO deprecate :raise

  raise I18n::ArgumentError if key.is_a?(String) && key.empty?

  result = catch(:exception) do
    if key.is_a?(Array)
      key.map { |k| backend.translate(locale, k, options) }
    else
      backend.translate(locale, key, options)
    end
  end
  result.is_a?(MissingTranslation) ? handle_exception(handling, result, locale, key, options) : result
end

...使用上述不同的方法调用时表现不同。传入变量而不是内联哈希值时,locale始终设置为config.locale,并且无法运行内置区域设置回退机制(无论:locale是否存在哈希变量。)然而,在IRB测试中,我找不到#x分辨方法的方法。

我目前通过将哈希内容复制粘贴到受影响的应用程序中的每个#translate调用来解决这个问题,但是很高兴知道这里有什么。

2 个答案:

答案 0 :(得分:4)

在每次调用方法之前,是否将 new 对象分配给变量?我怀疑没有,并且观察到的错误不是由于如何被调用,而是它对传递的对象做了什么

也就是说, translate方法可能会导致/导致输入的副作用,因为它会修改传入的对象。在这种情况下,options.delete(...)将创建一个副作用,可能导致后续调用中的意外行为:虽然“变量相同”,但变量引用的对象已被静默破坏。修复(和“正确”代码)是消除这些副作用。

快乐的编码。

答案 1 :(得分:2)

不,它们完全相同:

def x(*a)
  puts a.inspect
end

x('foo', y: 'bar', z: 'baz')
 => ["foo", {:y=>"bar", :z=>"baz"}]

@yz = { y: 'bar', z: 'baz' }

x('foo', @yz)
 => ["foo", {:y=>"bar", :z=>"baz"}]

请注意,您使用的语法仅适用于Ruby 1.9,而不适用于1.8