使用do块与大括号{}
【腾讯云】亏本大甩卖,服务器4核16G 1年370元(带宽12M,系统盘120GB SSD盘,月流量2000GB)!!!!!!
云产品 配置 价格
服务器 1核2G,带宽5M,系统盘50GB SSD盘,月流量500GB 38元/年
MySQL 1核1G 19元/年
服务器 16核32G,带宽18M,系统盘250GB SSD盘,月流量5000GB 1197元/年
点我进入腾讯云,查看更多详情

New to ruby, put on your newbie gloves.

Is there any difference (obscure or practical) between the following two snippets?

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

my_array = [:uno, :dos, :tres]
my_array.each do |item| 
    puts item
end

I realize the brace syntax would allow you to place the block on one line

my_array.each { |item| puts item }

but outside of that are there any compelling reasons to use one syntax over the other?

#0

Ruby cookbook says bracket syntax has higher precedence order than do..end

Keep in mind that the bracket syntax has a higher precedence than the do..end syntax. Consider the following two snippets of code:

1.upto 3 do |x|
  puts x
end

1.upto 3 { |x| puts x }
# SyntaxError: compile error

Second example only works when parentheses is used, 1.upto(3) { |x| puts x }

#1

This is a bit old question but I would like to try explain a bit more about {} and do .. end

like it is said before

bracket syntax has higher precedence order than do..end

but how this one makes difference:

method1 method2 do
  puts "hi"
end

in this case, method1 will be called with the block of do..end and method2 will be passed to method1 as an argument! which is equivalent to method1(method2){ puts "hi" }

but if you say

method1 method2{
  puts "hi"
}

then method2 will be called with the block then the returned value will be passed to method1 as an argument. Which is equivalent to method1(method2 do puts "hi" 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
}

#### output ####

#inside method2
#no block passed to method2
#inside method1
#method1 arg = method2 returned without block
#Block passed to method1
#method1 block is running

#inside method2
#Block passed to method2
#method2 block is running
#inside method1
#method1 arg = 
#No block passed to method1

#2

Generally, the convention is to use {} when you are doing a small operation, for example, a method call or a comparison, etc. so this makes perfect sense:

some_collection.each { |element| puts element }

But if you have slightly complex logic that goes to multiple lines then use do .. end like:

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

Basically, it comes down to, if your block logic goes to multiple lines and cannot be fitted on the same line then use do .. end and if your block logic is simple and just a simple/single line of code then use {}.

#3

There are two common styles for choosing do end vs. { } for blocks in Ruby:

The first and very common style was popularized by Ruby on Rails, and is based on a simple rule of single vs. multi-line:

  • Use braces { } for single-line blocks
  • Use do end for multi-line blocks

This makes sense because do/end reads badly in a one-liner, but for multi-line blocks, leaving a closing } hanging on its own line is inconsistent with everything else that uses end in ruby, such as module, class & method definitions (def etc.) and control structures (if, while, case, etc.)

The second, less-frequently seen style is known as semantic, or "Weirich Braces", proposed by the late, great rubyist Jim Weirich:

  • Use do end for procedural blocks
  • Use braces { } for functional blocks

This means that when the block is evaluated for its return value, it should be chainable, and the {} braces make more sense for method chaining.

On the other hand, when the block is evaluated for its side-effects, then the return value is of no consequence, and the block is just "doing" something, so it does not make sense to be chained.

This distinction in the syntax conveys visual meaning about the evaluation of the block, and whether or not you should care about its return value.

For example, here the return value of the block is applied to every item:

items.map { |i| i.upcase }

However, here it's not using the block's return value. It's operating procedurally, and doing a side-effect with it:

items.each do |item|
  puts item
end

Another benefit of the semantic style is that you don't need to change braces to do/end just because a line was added to the block.

As an observation, coincidentally functional blocks are frequently a one-liner, and procedural blocks (e.g. config) are multi-line. So, following the Weirich style ends up looking almost the same as the Rails style.

#4

I used the Weirich style for years, but just moved away from this to always use braces. I don't remember to ever have used the info from the block style, and the definition is kinda vague. For example:

date = Timecop.freeze(1.year.ago) { format_date(Time.now) }
customer = Timecop.freeze(1.year.ago) { create(:customer) }

Are these procudual or functional?

And the line count thing is just useless in my opinion. I know, whether there are 1 or more lines, and why exactly should I change the style just because I've added or removed lines?

推荐文章

Asp.netmvc 3模型在数据库中的应用

Asp.netmvc 3模型在数据库中的应用

推荐文章

用Java运行Unix命令

用Java运行Unix命令

推荐文章

从子级触发事件,但让父级在Jquery中监听它

从子级触发事件,但让父级在Jquery中监听它

推荐文章

基于输入的URL重定向,但如果输入URL不存在,则发送回同一页

基于输入的URL重定向,但如果输入URL不存在,则发送回同一页

推荐文章

在firefox中,Max width在一个灵活的盒子模型中不起作用?

在firefox中,Max width在一个灵活的盒子模型中不起作用?

推荐文章

P4PHP API-如何用-f标志保存p4客户端?

P4PHP API-如何用-f标志保存p4客户端?

推荐文章

应用程序上的短期用户界面冻结将进入前台

应用程序上的短期用户界面冻结将进入前台

推荐文章

Highchart显示和隐藏错误

Highchart显示和隐藏错误

推荐文章

如何将用户权限添加到元数据库.xml在重新启动IIS(Internet信息服务)时不会丢失它们?

如何将用户权限添加到元数据库.xml在重新启动IIS(Internet信息服务)时不会丢失它们?

推荐文章

解析方法或重载构造函数

解析方法或重载构造函数

推荐文章

在领域驱动的MVC世界中,比较器生活在哪里?

在领域驱动的MVC世界中,比较器生活在哪里?

推荐文章

处理HTML字符编码问题

处理HTML字符编码问题

推荐文章

setTitle方法在子活动中不起作用

setTitle方法在子活动中不起作用

推荐文章

MySQL Count函数不能正常工作

MySQL Count函数不能正常工作

推荐文章

在java中解析XML的访问权

在java中解析XML的访问权

推荐文章

iPhone:哪个控制器应该处理CRUD逻辑?

iPhone:哪个控制器应该处理CRUD逻辑?