天道酬勤,学无止境

Ruby:将proc转换为lambda吗?(Ruby: convert proc to lambda?)

问题

是否可以将proc风味的Proc转换为lambda风味的Proc?

有点惊讶,这至少在1.9.2中不起作用:

my_proc = proc {|x| x}
my_lambda = lambda &p
my_lambda.lambda? # => false!
回答1

要追踪这个问题有些棘手。 在寻找Proc#lambda的文档? 对于1.9,关于proclamdba的区别进行了相当长的讨论。

结果是, lambda强制使用了正确数量的参数,而proc没有。 从该文档中,此示例显示了将proc转换为lambda的唯一方法:

即使给出了非lambda Proc对象, define_method始终定义没有技巧的方法。 这是不保留技巧的唯一例外。

 class C define_method(:e, &proc {}) end C.new.e(1,2) => ArgumentError C.new.method(:e).to_proc.lambda? => true

如果要避免污染任何类,可以只在匿名对象上定义单例方法,以将proc强制为lambda

def convert_to_lambda &block
  obj = Object.new
  obj.define_singleton_method(:_, &block)
  return obj.method(:_).to_proc
end

p = Proc.new {}
puts p.lambda? # false
puts(convert_to_lambda(&p).lambda?) # true

puts(convert_to_lambda(&(lambda {})).lambda?) # true
回答2

这是不可能的PROC转换为拉姆达没有麻烦。 Mark Rushakoff的答案并未在代码块中保留self的值,因为self成为Object.new 。 Pawel Tomulik的答案不适用于Ruby 2.1,因为define_singleton_method现在返回一个Symbol,所以to_lambda2返回:_.to_proc

我的回答也是错误的

def convert_to_lambda &block
  obj = block.binding.eval('self')
  Module.new.module_exec do
    define_method(:_, &block)
    instance_method(:_).bind(obj).to_proc
  end
end

它在代码块中保留self的值:

p = 42.instance_exec { proc { self }}
puts p.lambda?      # false
puts p.call         # 42

q = convert_to_lambda &p
puts q.lambda?      # true
puts q.call         # 42

但是它失败并带有instance_exec

puts 66.instance_exec &p    # 66
puts 66.instance_exec &q    # 42, should be 66

我必须使用block.binding.eval('self')来找到正确的对象。 我将方法放在匿名模块中,因此它永远不会污染任何类。 然后,将我的方法绑定到正确的对象。 尽管该对象从不包含模块,但此方法可行! 绑定方法产生一个lambda。

66.instance_exec &q失败,因为q秘密地是绑定到42的方法,而instance_exec无法重新绑定该方法。 可以通过扩展q来暴露未绑定的方法,然后重新定义instance_exec以将未绑定的方法绑定到另一个对象来解决此问题。 即使这样, module_execclass_exec仍然会失败。

class Array
  $p = proc { def greet; puts "Hi!"; end }
end
$q = convert_to_lambda &$p
Hash.class_exec &$q
{}.greet # undefined method `greet' for {}:Hash (NoMethodError)

问题是Hash.class_exec &$q定义Array#greet而不是Hash#greet 。 (尽管$q秘密地是一个匿名模块的方法,但它仍然在Array中而不是在匿名模块中定义方法。)使用原始proc时, Hash.class_exec &$p将定义Hash#greet 。 我得出结论, convert_to_lambda是错误的,因为它不适用于class_exec

回答3

这是可能的解决方案:

class Proc
  def to_lambda
    return self if lambda?

    # Save local reference to self so we can use it in module_exec/lambda scopes
    source_proc = self

    # Convert proc to unbound method
    unbound_method = Module.new.module_exec do
      instance_method( define_method( :_proc_call, &source_proc ))
    end

    # Return lambda which binds our unbound method to correct receiver and calls it with given args/block
    lambda do |*args, &block|
      # If binding doesn't changed (eg. lambda_obj.call) then bind method to original proc binding,
      # otherwise bind to current binding (eg. instance_exec(&lambda_obj)).
      unbound_method.bind( self == source_proc ? source_proc.receiver : self ).call( *args, &block )
    end
  end

  def receiver
    binding.eval( "self" )
  end
end

p1 = Proc.new { puts "self = #{self.inspect}" }
l1 = p1.to_lambda

p1.call #=> self = main
l1.call #=> self = main

p1.call( 42 ) #=> self = main
l1.call( 42 ) #=> ArgumentError: wrong number of arguments (1 for 0)

42.instance_exec( &p1 ) #=> self = 42
42.instance_exec( &l1 ) #=> self = 42

p2 = Proc.new { return "foo" }
l2 = p2.to_lambda

p2.call #=> LocalJumpError: unexpected return
l2.call #=> "foo"

应该适用于Ruby 2.1+

回答4

用于将proc转换为lambda的跨ruby兼容库:https://github.com/schneems/proc_to_lambda

宝石:http://rubygems.org/gems/proc_to_lambda

回答5

上面的代码不能很好地与instance_exec配合使用,但是我认为有一个简单的解决方法。 这里有一个说明问题和解决方案的示例:

# /tmp/test.rb
def to_lambda1(&block)
  obj = Object.new
  obj.define_singleton_method(:_,&block)
  obj.method(:_).to_proc
end

def to_lambda2(&block)
  Object.new.define_singleton_method(:_,&block).to_proc
end


l1 = to_lambda1 do
  print "to_lambda1: #{self.class.name}\n"
end
print "l1.lambda?: #{l1.lambda?}\n"

l2 = to_lambda2 do
  print "to_lambda2: #{self.class.name}\n"
end
print "l2.lambda?: #{l2.lambda?}\n"

class A; end

A.new.instance_exec &l1
A.new.instance_exec &l2

to_lambda1基本上是Mark提出的实现, to_lambda2是“固定”代码。

上面脚本的输出是:

l1.lambda?: true
l2.lambda?: true
to_lambda1: Object
to_lambda2: A

实际上,我希望instance_exec输出A ,而不是Objectinstance_exec应该更改绑定)。 我不知道为什么它的工作原理不同,但是我想define_singleton_method返回一个尚未绑定到Object的方法,而Object#method返回一个已经绑定的方法。

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 何时使用lambda,何时使用Proc.new?(When to use lambda, when to use Proc.new?)
    问题 在Ruby 1.8中,一方面proc / lambda与另一方面Proc.new之间存在细微的差异。 这些区别是什么? 您能提供有关如何决定选择哪一个的指导吗? 在Ruby 1.9中,proc和lambda是不同的。 这是怎么回事? 回答1 使用lambda创建的Proc.new和使用Proc.new创建的Proc.new之间的另一个重要但细微的区别是它们如何处理return语句: 在由lambda创建的proc中, return语句仅从proc本身返回在Proc.new创建的proc中, return语句有点令人惊讶:它不仅从proc还从封装proc的方法中返回控制! 这是由lambda创建的proc的return 。 它的行为可能与您预期的一样: def whowouldwin mylambda = lambda {return "Freddy"} mylambda.call # mylambda gets called and returns "Freddy", and execution # continues on the next line return "Jason" end whowouldwin #=> "Jason" 现在,这是一个由Proc.new创建的proc的return执行相同的操作。 您将看到以下其中一种情况,其中Ruby打破了广受赞誉的
  • Ruby中的proc和lambda有什么区别?(What's the difference between a proc and a lambda in Ruby?)
    问题 您什么时候会使用一个而不是另一个? 回答1 一种区别是它们处理参数的方式。 使用proc {}和Proc.new {}创建proc是等效的。 但是,使用lambda {}为您提供了一个过程,可以检查传递给它的参数数量。 来自ri Kernel#lambda : 与Proc.new等效,除了生成的Proc对象检查调用时传递的参数数量。 一个例子: p = Proc.new {|a, b| puts a**2+b**2 } # => #<Proc:0x3c7d28@(irb):1> p.call 1, 2 # => 5 p.call 1 # => NoMethodError: undefined method `**' for nil:NilClass p.call 1, 2, 3 # => 5 l = lambda {|a, b| puts a**2+b**2 } # => #<Proc:0x15016c@(irb):5 (lambda)> l.call 1, 2 # => 5 l.call 1 # => ArgumentError: wrong number of arguments (1 for 2) l.call 1, 2, 3 # => ArgumentError: wrong number of arguments (3 for 2) 此外,正如Ken所指出的那样
  • 可以在Ruby中为map(&:method)语法提供参数吗?(Can you supply arguments to the map(&:method) syntax in Ruby?)
    问题 您可能熟悉以下Ruby速记( a是一个数组): a.map(&:method) 例如,在irb中尝试以下操作: >> a=[:a, 'a', 1, 1.0] => [:a, "a", 1, 1.0] >> a.map(&:class) => [Symbol, String, Fixnum, Float] 语法a.map(&:class)是a.map {|x| x.class}的简写。 a.map {|x| x.class} 。 在“ Ruby中的map(&:name)意味着什么?”中阅读有关此语法的更多信息。 通过&:class语法,您将为每个数组元素创建一个方法调用class 。 我的问题是:您可以为方法调用提供参数吗? 如果是这样,怎么办? 例如,如何转换以下语法 a = [1,3,5,7,9] a.map {|x| x + 2} 到&:语法? 我不建议&:语法更好。 我仅对将&:语法与参数一起使用的机制感兴趣。 我假设您知道+是Integer类的方法。 您可以在irb中尝试以下操作: >> a=1 => 1 >> a+(1) => 2 >> a.send(:+, 1) => 2 回答1 您可以在Symbol上创建一个简单的补丁,如下所示: class Symbol def with(*args, &block) ->(caller, *rest) { caller
  • 何时在Ruby on Rails中使用lambda?(When to use a lambda in Ruby on Rails?)
    问题 什么时候应该使用lambda或proc? 我已经看到它们被描述为匿名函数,但是我很难理解这个概念。 我希望您能在Ruby中使用任何链接或示例,尤其是在Ruby on Rails中。 回答1 http://augustl.com/blog/2008/procs_blocks_and_anonymous_functions/简要介绍了什么是block / procs / lambda,如何使用它们以及它们与其他语言的功能比较。 它肯定回答了您的问题。 请注意,上一节“关于lambdas的说明”提到的一点仅在Ruby 1.8中适用,而在1.9版中已更改-Ruby:Proc.new {'waffles'}与proc {'waffles'} 回答2 我看不出您在Ruby on Rails和Ruby之间有什么区别。 如果您正在编写Ruby on Rails应用程序,那么您正在编写Ruby代码,因此,如果它在Ruby中有用,则在Ruby on Rails中也应有用。 无论如何,这篇文章,《 Ruby中的一些有用的闭包》应该是有帮助的,以及以下内容:http://www.robertsosinski.com/2008/12/21/understanding-ruby-blocks-procs-and-lambdas/ 回答3 什么是lambda? 与您的irb一起尝试。 lam =
  • 在Ruby块中使用“返回”(Using 'return' in a Ruby block)
    问题 我正在尝试将Ruby 1.9.1用于嵌入式脚本语言,以便将“最终用户”代码写入Ruby块中。 与此相关的一个问题是,我希望用户能够在块中使用'return'关键字,因此他们不必担心隐式的返回值。 考虑到这一点,这是我想做的事情: def thing(*args, &block) value = block.call puts "value=#{value}" end thing { return 6 * 7 } 如果在上面的示例中使用“ return”,则会收到LocalJumpError。 我知道这是因为所讨论的块是Proc而不是lambda。 如果删除“ return”,该代码将起作用,但在这种情况下,我真的更希望能够使用“ return”。 这可能吗? 我尝试将块转换为lambda,但结果是相同的。 回答1 在这种情况next ,只需使用next : $ irb irb(main):001:0> def thing(*args, &block) irb(main):002:1> value = block.call irb(main):003:1> puts "value=#{value}" irb(main):004:1> end => nil irb(main):005:0> irb(main):006:0* thing { irb(main):007:1*
  • 您如何在Ruby中称呼&:运算符? [复制](What do you call the &: operator in Ruby? [duplicate])
    问题 这个问题已经在这里有了答案: 11年前关闭。 可能重复: Ruby / Ruby on Rails和号冒号快捷方式 map(&:name)在Ruby中是什么意思? 我正在阅读Stackoverflow,偶然发现了以下代码 array.map(&:to_i) 好的,很容易看到这段代码的作用,但是我想更多地了解&:构造,这是我之前从未见过的。 不幸的是,我只能想到的不是“ lambda”。 Google告诉我,Ruby中的Lambda语法为->->(x,y){ x * y } 因此,除了调用单个方法之外,谁都知道神秘的&:是什么以及它能做什么? 回答1 这里有一些动人的部分,但是发生的事情是Symbol#to_proc转换。 这是Ruby 1.9及更高版本的一部分,如果使用更高版本的Rails,也可以使用。 首先,在Ruby中, :foo表示“符号foo ”,因此实际上是您要查看的两个单独的运算符,而不是大的&:运算符。 当您说foo.map(&bar) ,您在告诉Ruby,“向foo对象发送一条消息,以调用map方法(带有我已经定义的块bar ”。 如果bar还不是Proc对象,Ruby将尝试使其成为一个对象。 在这里,我们实际上没有传递块,而是传递了称为bar的符号。 因为我们在Symbol上有一个隐式的to_proc转换,所以Ruby会看到并使用它。 原来
  • 如何在Ruby中封送lambda(Proc)?(How do I marshal a lambda (Proc) in Ruby?)
    问题 Joe Van Dyk询问了Ruby邮件列表: 你好, 在Ruby中,我想您无法编组lambda / proc对象,对吗? 是否可以用lisp或其他语言? 我正在尝试做的是: l = lamda { ... } Bj.submit "/path/to/ruby/program", :stdin => Marshal.dump(l) 因此,我正在向BackgroundJob发送一个lambda对象,该对象包含要执行的操作的上下文/代码。 但是,猜测那是不可能的。 我最终整理了一个正常的红宝石对象,其中包含程序运行后的操作说明。 乔 回答1 您无法封送Lambda或Proc。 这是因为它们都被视为闭包,这意味着它们会在定义它们的内存周围关闭并可以引用它。 (要封送它们,您必须封送它们在创建时可以访问的所有内存。) 正如Gaius指出的那样,您可以使用ruby2ruby获取该程序的字符串。 也就是说,您可以封送代表红宝石代码的字符串,然后在以后重新评估它。 回答2 您也可以只将代码作为字符串输入: code = %{ lambda {"hello ruby code".split(" ").each{|e| puts e + "!"}} } 然后用eval执行 eval code 这将返回一个红宝石lamda。 使用%{}格式可对字符串进行转义,但仅在不匹配的花括号上关闭。
  • 为什么显式收益在Proc中有所作为?(Why does explicit return make a difference in a Proc?)
    问题 def foo f = Proc.new { return "return from foo from inside proc" } f.call # control leaves foo here return "return from foo" end def bar b = Proc.new { "return from bar from inside proc" } b.call # control leaves bar here return "return from bar" end puts foo # prints "return from foo from inside proc" puts bar # prints "return from bar" 我认为return关键字在Ruby中是可选的,无论您是否要求,您总是会return ing。 鉴于此,我发现foo和bar具有不同的输出是令人惊讶的,这取决于foo在Proc f包含显式return的事实。 有人知道为什么会这样吗? 回答1 Ruby具有三个构造: 块不是对象,而是由{ ... }或do ... end 。 proc是由Proc.new或proc创建的Proc对象。 lambda是由lambda (或Ruby 1.8中的proc )创建的Proc 。 Ruby具有三个从某事物返回的关键字:
  • Ruby: convert proc to lambda?
    Is it possible to convert a proc-flavored Proc into a lambda-flavored Proc? Bit surprised that this doesn't work, at least in 1.9.2: my_proc = proc {|x| x} my_lambda = lambda &p my_lambda.lambda? # => false!
  • 如何在Ruby中创建充当False的对象(How to create an Object who act as a False in Ruby)
    问题 我想做这个 lol = Klass.new(values) unless lol print "false" end lol.other_method # it is not nil or false, it is a Klass instance! 但是,在这种情况下,哈哈不是nil或false,而是可以基于某些内部值充当false的对象。 我有这个选择 lol = Klass.new(values) unless lol.to_bool print "false" end 但这是丑陋的恕我直言。 我在考虑扩展FalseClass或玩==,但没有成功。 有任何想法吗? 回答1 不幸的是,这是不可能的。 这是Ruby不是面向对象的烦人情况之一。 在OO中,必须有可能模拟一个对象(实际上,这取决于OO,这是OO的定义-记住OO是出于模拟而产生的),但是不可能建立一个对象来模拟。模拟false 。 这是因为,在Ruby中,条件控制结构被烤成语言,并没有转化为消息发送,而在其他面向对象的语言,他们只是普通的消息发送(或者至少转化为消息发送,就像for Ruby的转换进入each )。 例如,在Smalltalk中,布尔实际上是使用从Lambda微积分中得知的布尔的Church编码实现的,然后转换为Ruby,它们看起来像这样: class FalseClass def if(
  • Ruby Proc语法(Ruby Proc Syntax)
    问题 我昨天在这里提出的一个问题的答案是以下一段Ruby代码: def overlap?(r1,r2) r1.include?(r2.begin) || r2.include?(r1.begin) end def any_overlap?(ranges) ranges.sort_by(&:begin).each_cons(2).any? do |r1,r2| overlap?(r1, r2) end end 我得到了each_cons ,但是&:begin表示法是什么呢? 从语法地狱救我! 谢谢! 回答1 当在呼叫的最后一个参数前加上&前缀时&您会清楚地表明您是在发送一个块,而不是普通的参数。 好的,在method(&:something) , :something是一个符号,而不是proc ,因此Ruby会自动调用to_proc方法以获取实际块。 Rails伙计们(现在也包括香草Ruby)巧妙地将其定义为: class Symbol def to_proc proc { |obj, *args| obj.send(self, *args) } end end 这就是为什么您可以这样做: >> [1, 2, 3].map(&:to_s) # instead of [1, 2, 3].map { |n| n.to_s } => ["1", "2", "3"] [edit]注意
  • map(&:name)在Ruby中是什么意思?(What does map(&:name) mean in Ruby?)
    问题 我在RailsCast中找到了以下代码: def tag_names @tag_names || tags.map(&:name).join(' ') end 什么是(&:name)在map(&:name)是什么意思? 回答1 这是tags.map(&:name.to_proc).join(' ')的简写 如果foo是具有to_proc方法的对象,则可以将其作为&foo传递给方法,该方法将调用foo.to_proc并将其用作方法的块。 Symbol#to_proc方法最初是由ActiveSupport添加的,但已集成到Ruby 1.8.7中。 这是它的实现: class Symbol def to_proc Proc.new do |obj, *args| obj.send self, *args end end end 回答2 许多人不知道的另一个很酷的速记是 array.each(&method(:foo)) 这是的简写 array.each { |element| foo(element) } 通过调用method(:foo)我们从self那里获取了一个Method对象,该对象代表其foo方法,并使用&表示它具有to_proc方法,可将其转换为Proc 。 当您想做无指向性的样式时,这非常有用。 一个示例是检查数组中是否有任何与字符串"foo"相等的字符串。 有常规方法
  • 您如何对Ruby代码进行字符串化/序列化?(How do you stringize/serialize Ruby code?)
    问题 我希望能够在我的Ruby代码中编写一个lambda / Proc,对其进行序列化,以便可以将其写入磁盘,然后在以后执行该lambda。 有点像... x = 40 f = lambda { |y| x + y } save_for_later(f) 后来,在另一次Ruby解释器运行中,我想说... f = load_from_before z = f.call(2) z.should == 42 Marshal.dump不适用于Procs。 我知道Perl有Data :: Dump :: Streamer,在Lisp中这很简单。 但是有没有办法在Ruby中做到这一点? 换句话说,什么是执行save _ for _ later ? 编辑:下面我的答案很好,但是它不会关闭自由变量(如x )并将它们与lambda一起序列化。 所以在我的例子中... x = 40 s = save_for_later { |y| x + y } # => "lambda { |y|\n (x + y)\n}" ...字符串输出不包含x的定义。 是否有一种解决方案可以考虑到这一点,也许可以通过序列化符号表来解决? 您可以在Ruby中访问它吗? 编辑2 :我更新了我的答案以合并序列化局部变量。 这似乎可以接受。 回答1 使用Ruby2Ruby def save_for_later(&block)
  • Ruby块的最佳解释? [关闭](Best explanation of Ruby blocks? [closed])
    问题 关门了。 这个问题是基于意见的。 它当前不接受答案。 想要改善这个问题吗? 更新问题,以便可以通过编辑此帖子以事实和引用的形式回答。 7年前关闭。 改善这个问题 您可以共享的Ruby块的最佳解释是什么? 用法和编写代码可能会花费很多时间? 回答1 我对此回答提供了自己的解释,并做了一些修改: Ruby中的“块”与通用编程术语“代码块”或“代码块”不同。 假装一下以下(无效的)Ruby代码实际上有效: def add10( n ) puts "#{n} + 10 = #{n+10}" end def do_something_with_digits( method ) 1.upto(9) do |i| method(i) end end do_something_with_digits( add10 ) #=> "1 + 10 = 11" #=> "2 + 10 = 12" ... #=> "9 + 10 = 19" 尽管该代码无效,但它的意图(将某些代码传递给某个方法并让该方法运行该代码)可以在Ruby中以多种方式实现。 这些方法之一是“块”。 Ruby中的Block非常非常类似于一种方法:它可以接受一些参数并为其运行代码。 每当您看到foo{ |x,y,z| ... } foo{ |x,y,z| ... }或foo do |x,y,z| ... end foo do |x
  • 在Ruby中更改Proc的绑定(Change the binding of a Proc in Ruby)
    问题 我有以下代码: l = lambda { a } def some_function a = 1 end 我只想通过lambda和一个特殊的作用域来访问a ,该作用域已在示例中的some_function内部定义a已经存在的位置,或者稍后不久就在与该作用域相同的范围内: l = lambda { a } a = 1 l.call 然后,我发现在调用l ,它仍在使用其自己的绑定,而不是调用它的新绑定。 然后我尝试将其用作: l.instance_eval do a = 1 call end 但这也失败了,我无法解释原因,这很奇怪。 我知道解决方案之一是使用eval ,在其中可以特殊绑定并在文本中执行一些代码,但是我真的不想这样使用。 而且,我知道它能够使用全局变量或实例变量。 但是,实际上我的代码在更深的嵌入式环境中,因此,如果不是很必要,我不想破坏完整的部分。 我已经在文档中引用了Proc类,并且发现了一个引用Proc上下文的函数名称binding 。 尽管该函数仅提供一种访问其绑定的方法,但不能更改它,除非使用Binding#eval 。 它也评估文本,这正是我不喜欢做的事情。 现在的问题是,我是否有更好(或更优雅)的方式来实现这一目标? 还是使用eval已经是常规方式? 编辑以回复@Andrew: 好的,这是我在编写词法分析器时遇到的一个问题
  • Ruby - lambda vs. Proc.new [duplicate]
    This question already has answers here: Closed 9 years ago. Possible Duplicate: What's the difference between a proc and a lambda in Ruby? When run this Ruby code: def func_one proc_new = Proc.new {return "123"} proc_new.call return "456" end def func_two lambda_new = lambda {return "123"} lambda_new.call return "456" end puts "The result of running func_one is " + func_one puts "" puts "The result of running func_two is " + func_two The result that I get is as follows: The result of running func_one is 123 The result of running func_two is 456 As for func_two, where is the the value of the
  • How do I marshal a lambda (Proc) in Ruby?
    Joe Van Dyk asked the Ruby mailing list: Hi, In Ruby, I guess you can't marshal a lambda/proc object, right? Is that possible in lisp or other languages? What I was trying to do: l = lamda { ... } Bj.submit "/path/to/ruby/program", :stdin => Marshal.dump(l) So, I'm sending BackgroundJob a lambda object, which contains the context/code for what to do. But, guess that wasn't possible. I ended up marshaling a normal ruby object that contained instructions for what to do after the program ran. Joe
  • Ruby中的不同括号是什么意思?(What do the different brackets in Ruby mean?)
    问题 在Ruby中, {}和[]什么区别? {}似乎同时用于代码块和哈希。 []仅用于数组吗? 该文件不是很清楚。 回答1 这取决于上下文: 单独使用或分配给变量时, []创建数组,而{}创建哈希。 例如a = [1,2,3] # an array b = {1 => 2} # a hash 可以重写[]作为自定义方法,通常用于从哈希中获取内容(标准库将[]为与fetch相同的哈希方法) 还有一个约定,将它用作类方法的方式与在C#或Java中使用static Create方法的方式相同。 例如a = {1 => 2} # create a hash for example puts a[1] # same as a.fetch(1), will print 2 Hash[1,2,3,4] # this is a custom class method which creates a new hash 有关最后一个示例,请参见Ruby Hash文档。 这可能是最棘手的问题- {}也是块的语法,但仅在参数parens传递到方法之外时才使用。 当您调用没有parens的方法时,Ruby会查看您放在逗号的位置以弄清楚参数的结束位置(如果键入了参数,parens会在哪里) 1.upto(2) { puts 'hello' } # it's a block 1.upto 2 { puts
  • What's the difference between a proc and a lambda in Ruby?
    And when would you use one rather than the other?
  • Change the binding of a Proc in Ruby
    I have this code: l = lambda { a } def some_function a = 1 end I just want to access a by the lambda and a special scope which has defined a already somewhere like inside some_function in the example, or just soon later in the same scope as: l = lambda { a } a = 1 l.call Then I found when calling l, it is still using its own binding but not the new one where it was called. And then I tried to use it as: l.instance_eval do a = 1 call end But this also failed, it is strange that I can't explain why. I know the one of the solution is using eval, in which I could special a binding and executing