【问题标题】:Is there a way to pass key-vals in one word like in Javascript?有没有一种方法可以像在 Javascript 中那样在一个单词中传递键值?
【发布时间】:2017-01-04 04:06:39
【问题描述】:

在 Javascript 中我可以这样做:

myVar = 1
obj = { myVar }
obj.myVar == 1 // true

在 Ruby 中,只能在方法中使用关键字参数做类似的事情:

def foo(a:, b:)
  [a,b]
end
foo(a: 1, b: 2) # [1,2]

在实践中,我发现这会使代码更加冗长。我不必像使用顺序参数那样命名一个变量,而是必须命名它两次才能将其作为参数发送:

def method_1(a:, b:)
  method_2(a: a, b: b) # repetition is here
end

我知道 ** 运算符用作关键字参数的 splat。但我宁愿不要在我的方法定义中加入 splats,因为它会使代码难以理解。

我并不是说关键字参数是无用的(它比解析 options 哈希更清楚),但如果它们支持常规哈希构造(如在 Javascript 中),它们会更有用。

无论如何,我想知道在 Ruby 本身中是否有任何方法可以做到这一点,或者我是否应该寻找另一种语言。

【问题讨论】:

  • 你真的要放弃这种语言,因为你必须输入a: a

标签: ruby


【解决方案1】:

无论如何,我想知道在 Ruby 本身中是否有任何方法可以做到这一点,

不,没有。

【讨论】:

  • 其实有办法做到这一点。
  • @akuhn 不,没有。你的方法还不够接近,它依赖于 MRI 特定的功能来获得有限的成功,从而产生一种 技术上 允许你避免重复变量名的语法,但需要你而是将它们包装在 binding.fun %w{...} 中,这几乎不是一种改进。应该避免这种伪语法扩展,发明自己的 Ruby 语言环境是不可取的。
  • 你可以选择更短的语法,比如重新定义`Kernel#``
  • @akuhn 这是一个更糟糕的主意。同样,Ruby 不支持这一点,并且通过修补核心类来发明自己的“足够接近”的语法是不可取的。你实际上是在制作一种只有你能理解的 Ruby 子语言。
  • 那叫做DSL, aka domain specific language,,是一个完美的Ruby应用。除了 lisp 之外,我不会知道另一种在创建“子语言”方面如此强大的语言。
【解决方案2】:

试试这个

class Binding
  def fun(names)
    names.zip(names.map(&method(:eval))).to_h
  end
end

a = 1
b = 2
h = binding.fun %w{a b}
p h
# => {"a"=>1, "b"=>2}

或者,

如果您不想在 Binding 类上定义函数

require 'debug_inspector'

def fun(names)
  RubyVM::DebugInspector.open do |inspector|
    names.zip(names.map { |name| eval(name, inspector.frame_binding(2)) }).to_h
  end
end

a = 1
b = 2
h = fun %w{a b}
p h
# => {"a"=>1, "b"=>2}

或者,

如果你想要真正简洁的语法并且不打算使用内置的反引号函数。

require 'debug_inspector'

def `(str) 
  # overrides builtin ` function, use with caution!
  RubyVM::DebugInspector.open do |inspector|
    str.split(?,).zip(eval("[#{str}]", inspector.frame_binding(2))).to_h
  end
end

a = 1
b = 2
h = `a, b`
p h
# => {"a"=>1, "b"=>2}

【讨论】:

  • 这与 OP 所指的语法完全不同。另外,您的代码不完整。你永远不会初始化binding。显然,您并没有像 OP 那样使用这种方法使您的代码更加简洁。
  • binding 不必初始化
  • 我承认这是我的一个错误。但即便如此,您是否真的认为您的代码与 OP 请求之类的 javascript 概念非常相似?
  • 据我了解,他们不想重复键和值。就我个人而言,我倾向于同意 meagar 的评论,但这不是由我来判断的。我只是展示了 Ruby 与 Javascript 的语法有多接近。
  • 我对那个反引号补丁进行了优化(当然给了你荣誉)-keyword_hash_builder。有了改进,我认为它并没有那么糟糕。
猜你喜欢
  • 1970-01-01
  • 2016-06-20
  • 1970-01-01
  • 2020-01-08
  • 2014-01-22
  • 1970-01-01
  • 2014-09-19
  • 2015-01-20
  • 1970-01-01
相关资源
最近更新 更多