Ruby 使用do块vs大括号{}

Ruby 使用do块vs大括号{},ruby,coding-style,Ruby,Coding Style,ruby新手,戴上你的新手手套 以下两个片段之间有什么区别(模糊的或实用的) my_array = [:uno, :dos, :tres] my_array.each { |item| puts item } my_array = [:uno, :dos, :tres] my_array.each do |item| puts item end 我意识到大括号语法允许您将块放在一行上 my_array.each { |item| puts item } 但除此之外,还有

ruby新手,戴上你的新手手套

以下两个片段之间有什么区别(模糊的或实用的)

my_array = [:uno, :dos, :tres]
my_array.each { |item| 
    puts item
}

my_array = [:uno, :dos, :tres]
my_array.each do |item| 
    puts item
end
我意识到大括号语法允许您将块放在一行上

my_array.each { |item| puts item }
但除此之外,还有任何令人信服的理由使用一种语法而不是另一种语法吗?

说括号语法的优先顺序比
do..end

def method1(var)
    puts "inside method1"
    puts "method1 arg = #{var}"
    if block_given?
        puts "Block passed to method1"
        yield "method1 block is running"
    else
        puts "No block passed to method1"
    end
end

def method2
    puts"inside method2"
    if block_given?
        puts "Block passed to method2"
        return yield("method2 block is running")
    else
        puts "no block passed to method2"
        return "method2 returned without block"
    end
end

#### test ####

method1 method2 do 
    |x| puts x
end

method1 method2{ 
    |x| puts x
}
请记住,括号语法 优先级高于 do..end语法。考虑以下事项 两段代码:


第二个示例仅在使用括号时有效,
1。最多(3){x}

通常,在执行小操作(例如,方法调用或比较等)时,约定使用
{}
。因此这非常有意义:

some_collection.each { |element| puts element }
但是,如果您有一个稍微复杂的逻辑,它涉及到多行,那么请使用
do。。结束
类似于:

1.upto(10) do |x|
  add_some_num = x + rand(10)
  puts '*' * add_some_num
end

基本上,它归结为,如果块逻辑到多行,并且不能安装在同一行上,那么使用
do。。结束
,如果您的块逻辑很简单,只是一行简单的代码,那么使用
{}
这是一个有点老的问题,但我想尝试解释更多关于
{}
的内容。。结束

def method1(var)
    puts "inside method1"
    puts "method1 arg = #{var}"
    if block_given?
        puts "Block passed to method1"
        yield "method1 block is running"
    else
        puts "No block passed to method1"
    end
end

def method2
    puts"inside method2"
    if block_given?
        puts "Block passed to method2"
        return yield("method2 block is running")
    else
        puts "no block passed to method2"
        return "method2 returned without block"
    end
end

#### test ####

method1 method2 do 
    |x| puts x
end

method1 method2{ 
    |x| puts x
}
就像以前说的那样

括号语法的优先顺序高于do..end

但这一点有什么不同:

method1 method2 do
  puts "hi"
end
在这种情况下,将使用
do..end
块调用method1,并将method2作为参数传递给method1!这相当于
method1(method2){put“hi”}

但是如果你说

method1 method2{
  puts "hi"
}
然后使用块调用method2,然后返回的值将作为参数传递给method1。这相当于
method1(method2不放“hi”端)

####输出####


对于Ruby中的块,选择
do end
{}
有两种常见的样式:

第一种也是非常常见的样式是Ruby on Rails推广的,它基于单行与多行的简单规则:

  • 对单行块使用大括号
    {}
  • 对多行块使用
    do end
这是有意义的,因为do/end在一行代码中读得不好,但对于多行代码块,将结束代码挂在自己的行上与ruby中使用的所有其他内容不一致,例如模块、类和方法定义(
def
等)和控制结构(
if
while
case
等)

第二种不太常见的风格是语义学,或“语义学”,由已故红宝石大师吉姆·魏里奇(Jim Weirich)提出:

  • 对程序块使用
    do end
  • 对功能块使用大括号
    {}
这意味着当对块的返回值求值时,它应该是可链接的,
{}
大括号对于方法链接更有意义

另一方面,当对块的副作用进行评估时,返回值是没有意义的,并且块只是在“做”一些事情,因此链接是没有意义的

语法中的这种区别传达了有关块计算的视觉意义,以及您是否应该关心其返回值

例如,此处块的返回值应用于每个项目:

items.map { |i| i.upcase }
然而,在这里,它并没有使用块的返回值。它是按程序操作的,并对其产生副作用:

items.each do |item|
  puts item
end
语义样式的另一个好处是,不需要仅仅因为向块中添加了一条线就将大括号更改为do/end


根据观察,巧合的功能块通常是一行程序块(如配置)是多行的。因此,遵循Weirich样式最终看起来几乎与Rails样式相同。

我使用Weirich样式多年,但只是从这一点转移到了始终使用大括号。。我不记得曾经使用过块样式的信息,并且定义有点模糊。例如:

date=Timecop.freeze(1.year.ago){format_date(Time.now)}
customer=Timecop.freeze(1.year.ago){create(:customer)}
这些是程序性的还是功能性的


在我看来,行数是没有用的。我知道,是否有1行或更多行,以及为什么仅仅因为我添加或删除了行就要更改样式?

好问题。我还对有经验的红宝石爱好者喜欢什么感兴趣。重复:这可能是、和的重复。你也可以写一个odo块的ne行,尽管它实际上只在执行eval(“my_array.each do | item |;put item;end”)之类的操作时才有用但是它在irb或pry中工作,没有eval和引号,你可能会遇到这样的情况。但是不要问我什么时候。这是另一个需要研究的主题。啊,明白了。所以因为优先顺序,当你使用do时,你把块作为一个附加参数传递,但是当你使用括号时,你传递的是block作为方法调用结果的第一个参数,位于左侧。我通常喜欢简短的答案,但bkdir的答案要清楚得多。我同意使用do/end来表示多行块,但如果我将其他方法链接到块的末尾,我会使用大括号。在风格上,我喜欢{…}.method().method()结束…end.method().method,但那可能就是我。同意,尽管我更喜欢将带有block的方法的结果赋给一个有意义的变量,然后调用另一个方法,如
result\u with_some\u condition=method{c | c.do\u something | | whatever};result_with_some_condition.。另一种_方法
只是让它更容易理解。但一般来说,我会避免火车失事。我想知道,为什么这种风格如此流行。是
items.each do |item|
  puts item
end