Ruby on rails 什么';这是什么&;红宝石块?它是如何在这里的方法中传递的?

Ruby on rails 什么';这是什么&;红宝石块?它是如何在这里的方法中传递的?,ruby-on-rails,ruby,Ruby On Rails,Ruby,在RubyonRails的书中看到了这段代码。第一个是视图,第二个是辅助模块。我不明白&block和属性={}是如何工作的。有人能给我一个解释这个的教程吗 <% hidden_div_if(@cart.items.empty?, :id => "cart") do %> <%= render(:partial => "cart", :object => @cart) %> <% end %> module StoreHelper def

在RubyonRails的书中看到了这段代码。第一个是视图,第二个是辅助模块。我不明白
&block
属性={}
是如何工作的。有人能给我一个解释这个的教程吗

<% hidden_div_if(@cart.items.empty?, :id => "cart") do %>
 <%= render(:partial => "cart", :object => @cart) %>
<% end %>

module StoreHelper
 def hidden_div_if(condition, attributes = {}, &block)
  if condition
   attributes["style"] = "display: none"
  end
   content_tag("div", attributes, &block)
  end
end
“购物车”)完成%>
“购物车”,对象=>@cart)%>
模块StoreHelper
def hidden_div_if(条件、属性={}、&block)
如果条件
属性[“样式”]=“显示:无”
结束
内容标签(“div”、属性和块)
结束
结束

是一种将一段Ruby代码发送到方法中,然后在该方法的范围内计算该代码的方法。在上面的示例代码中,它意味着一个部分命名的cart将在一个div中呈现。我认为这个术语在计算机科学中用于此

因此,在您的示例中,
&block
是:

“购物车”,:object=>@cart)%>

有关块、过程和lamda的一些很好的阅读和解释,请访问。

Re
attributes={}
,这只是一个带有默认值的方法参数。因此,如果调用
hidden\u div\u if(无论什么)
,即只传递第一个参数,
属性将默认为空哈希

这很有用,因为它简化了以后的设置
属性[“style”]
,因为
属性不必先初始化为散列。(尽管如此,这可以简单地作为
(attributes | |={})[“style”]=…


&block
只是稍微复杂一点

Ruby方法可以使用特殊语法
method(args){| block_args | block_code}
获取最后一个参数,即块
&block
基本上将该块作为
Proc
对象捕获到
block
变量中。所以
block
只是一个指向匿名过程的变量

当稍后调用
content\u标记
,并将
&block
作为其最后一个参数传递时,它将扩展为一个块,就像调用确实是
content\u标记(…){block最初传递给hidden\u if\u div}


也许我真的很困惑。你应该搜索“ruby默认参数”和“ruby块”。

它的工作原理如下:

@cart.items.empty?
是密码

:id=>“cart”
根据约定成为属性。如果参数散列中的{}是最后一个,则可以删除它

这个街区是

render(:partial=>“cart”,:object=>@cart)

因此,在函数中,如果购物车为空,它将添加属性 带有值“显示:无”的样式


然后它将创建一个div标记,其中填充了执行块的结果的内容,这将是使用@cart的内容呈现局部视图购物车的结果。

块是ruby的一个相当基本的部分。它们由
do | arg0,arg1 |。。。结束
{| arg0、arg1、arg2 |……}

它们允许您指定要传递给方法的回调。 可以通过两种方式调用此回调—通过捕获 通过指定前缀为
&
的最终参数或 使用
yield
关键字:

irb> def meth_captures(arg, &block)
       block.call( arg, 0 ) + block.call( arg.reverse , 1 )
     end
#=> nil
irb> meth_captures('pony') do |word, num|
       puts "in callback! word = #{word.inspect}, num = #{num.inspect}"
       word + num.to_s
     end
in callback! word = "pony" num = 0
in callback! word = "ynop" num = 1
#=> "pony0ynop1" 
irb> def meth_yields(arg)
       yield(arg, 0) + yield(arg.upcase, 1)
     end
#=> nil
irb> meth_yields('frog') do |word, num|
       puts "in callback! word = #{word.inspect}, num = #{num.inspect}"
       word + num.to_s
     end
in callback! word = "frog", num = 0
in callback! word = "FROG", num = 1
#=> "frog0FROG1"
请注意,我们的回调在每种情况下都是相同的-我们可以删除 通过将回调保存在对象中,然后将其传递给每个 方法。可以使用
lambda
捕获对象中的回调, 然后通过在方法前面加
&
来传递给该方法

irb> callback = lambda do |word, num|
       puts "in callback! word = #{word.inspect}, num = #{num.inspect}"
       word + num.to_s
     end
#=> #<Proc:0x0052e3d8@(irb):22>
irb> meth_captures('unicorn', &callback)
in callback! word = "unicorn", num = 0
in callback! word = "nrocinu", num = 1
#=> "unicorn0nrocinu1"
irb> meth_yields('plate', &callback)
in callback! word = "plate", num = 0
in callback! word = "PLATE", num = 1
#=> "plate0PLATE1"
irb>callback=lambda do | word,num|
将“放入回调!word={word.inspect},num={num.inspect}”
word+num.to\s
结束
#=> #
irb>meth_捕获('独角兽',&回调)
回电!word=“独角兽”,num=0
回电!word=“nrocinu”,num=1
#=>“独角兽0nRocinu1”
irb>meth_收益率('板块',&回调)
回电!word=“plate”,num=0
回电!word=“PLATE”,num=1
#=>“平板0平板1”
了解
&
作为函数最后一个参数前缀的不同用法非常重要

  • 在函数定义中,它捕获传递到该对象中的任何块
  • 在函数调用中,它将给定的回调对象展开为一个块

如果你环顾一下到处都在使用块,特别是在迭代器中,比如
Array#each
Ruby实现块、过程和lambda,它们在计算机科学界被称为闭包。 如果您开始学习Ruby,您将很快遇到如下代码

a = ["dog", "cat", "bird"]
a.alter_each! do |n, i|
  "#{i}_#{n}"
end
这是怎么回事

我们从一系列动物的名字开始,并分别称之为alter_!方法传递一个块。在这段代码中,我们可以指定如何更改每个项目。我们的示例将在每个动物名称前面加上它在数组中的位置。就像你们每个人一样!方法遍历它将执行的每个项,并传递值和索引。我们的块捕获这些参数,将索引作为名称的前缀,并返回结果。 现在让我们看看每个人的改变!方法

请注意,该方法没有指定任何参数,这是因为块会自动指定给yield关键字。调用yield就像函数传入数组中每个项的值和索引并覆盖原始值一样

class Array
  def alter_each!
    self.each_with_index do |n, i|
      self[i] = yield(n,i)
    end
  end
end
如果需要将参数传递给此方法,该怎么办

您可以修改方法签名以接受参数,并最终使用以符号and开头的参数捕获块。在下面的示例中,我们将使用&block参数捕获块,我们将调用该调用方法。这代替了使用收益率

class Array
  def modify_each!(add_one = true, &block)
    self.each_with_index do |n, i|
      j = (add_one) ? (i + 1) : i
      self[i] = block.call(n,j)
    end
  end
end

是的,Ruby中的块只是闭包。关于这一点的详细解释,请参阅。谢谢你的帮助,对我真的很有帮助!谢谢,伙计,这是一个很好的例子,但是在Fixnum上调用inspect有什么意义呢?我很抱歉读到这个,我的朋友