新的红宝石,穿上你的新手套.
以下两个片段之间是否有任何区别(模糊或实用)?
my_array = [:uno, :dos, :tres]
my_array.each { |item|
puts item
}
my_array = [:uno, :dos, :tres]
my_array.each do |item|
puts item
end
Run Code Online (Sandbox Code Playgroud)
我意识到括号语法允许你将块放在一行上
my_array.each { |item| puts item }
Run Code Online (Sandbox Code Playgroud)
但除此之外是否有任何令人信服的理由使用一种语法而不是另一种语法?
哪种款式首选?一个与另一个有充分的理由吗?
提前致谢!
1) cmds.each do |cmd|
end
2) cmds.each { |cmd|
}
Run Code Online (Sandbox Code Playgroud)
示例代码:
cmds = [ "create", "update", "list", "help" ]
# Block style one
#
cmds.each do |cmd|
puts "loop1, cmd: #{cmd}"
end
# Block style two
#
cmds.each { |cmd|
puts "loop2, cmd: #{cmd}"
}
Run Code Online (Sandbox Code Playgroud) 我偶尔看到begin...end在红宝石中使用没有任何块rescue,else,ensure,等语句之间.例如:
foo = begin
whatever = 3
"great"
42
end
Run Code Online (Sandbox Code Playgroud)
看起来编码器的意图是将begin...end块用于其块分组质量(就好像begin是do).就个人而言,我认为这种用法违反了最少惊喜的原则(begin暗示对我的异常处理).
begin...end以这种方式使用是否会产生任何意想不到的后果?做begin...end块有任何语义差异(也许在异常处理?),使这种用法很危险吗?
Ruby的语法令人难以置信的微妙,如果有一些奇怪的陷阱在这里等待,我也不会感到惊讶.
我提取了简单的例子:
require 'pp'
x = 1..3
pp x.map do |i| {:value => i, :double => (i*2)} end
pp x.map { |i| {:value => i, :double => (i*2)} }
pp(x.map do |i| {:value => i, :double => (i*2)} end)
pp(x.map { |i| {:value => i, :double => (i*2)} })
Run Code Online (Sandbox Code Playgroud)
我想知道为什么第一个pp产生:
[1, 2, 3]
Run Code Online (Sandbox Code Playgroud)
所有的演讲者都在给予:
[{:value=>1, :double=>2}, {:value=>2, :double=>4}, {:value=>3, :double=>6}]
Run Code Online (Sandbox Code Playgroud)
我认为它与运算符优先级有关.我在哪里可以找到好的解释?
任何人都可以解释为什么以下代码中止错误
irb(main):186:0> print ((1..10).collect do |x| x**2 end)
SyntaxError: (irb):186: syntax error, unexpected keyword_do_block,
expecting ')'
print ((1..10).collect do |x| x**2 end)
^
(irb):186: syntax error, unexpected keyword_end, expecting $end
print ((1..10).collect do |x| x**2 end)
^
from /usr/bin/irb:12:in `<main>'
Run Code Online (Sandbox Code Playgroud)
而具有相同功能的以下代码是否按预期工作?
irb(main):187:0> print ((1..10).collect { |x| x**2 })
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]=> nil
Run Code Online (Sandbox Code Playgroud)
我确实认为花括号"{}"可以在块定义中任意替换"do end".
我知道我可以通过省略print方法和第一个括号之间的空格来"修复"第一个调用,但我对解释它为什么表现不同感兴趣 .
可能重复:
Ruby块和未加括号的参数
我不确定我是否理解这种语法错误.我正在使用Carrierwave来管理Rails应用程序中的一些文件上传,我似乎错误地将一个块传递给其中一个方法.
以下是Carrierwave文档中的示例:
version :thumb do
process :resize_to_fill => [200,200]
end
Run Code Online (Sandbox Code Playgroud)
这就是我的所作所为:
version :full { process(:resize_to_limit => [960, 960]) }
version :half { process(:resize_to_limit => [470, 470]) }
version :third { process(:resize_to_limit => [306, 306]) }
version :fourth { process(:resize_to_limit => [176, 176]) }
Run Code Online (Sandbox Code Playgroud)
我得到以上不起作用syntax error, unexpected '}', expecting keyword_end.有趣的是,以下工作完美:
version :full do process :resize_to_limit => [960, 960]; end
version :half do process :resize_to_limit => [470, 470]; end
version :third do process :resize_to_limit => [306, …Run Code Online (Sandbox Code Playgroud) 我一直认为以下只是两种说法相同的方式:
[1,2,3].collect{|i| i * 2}
[1,2,3].collect do |i|
i * 2
end
Run Code Online (Sandbox Code Playgroud)
但是我在我的一个ERB模板中得到了一些奇怪的行为,其中两个语法似乎做了两件不同的事情.这段代码效果很好:
<%=raw @menu.collect { |m|
content_tag("li") {
link_to(m.capitalize, url_for(:controller => m))
}
} %>
Run Code Online (Sandbox Code Playgroud)
但当我重写它时:
<%=raw @menu.collect do |m|
content_tag("li") do
link_to(m.capitalize, url_for(:controller => m))
end
end %>
Run Code Online (Sandbox Code Playgroud)
...我最终得到了一串连结的@menu项目.我错过了什么吗?这里有一些细小的语法糖吗?
我最近开始学习ruby,我知道你可以使用这两种语法的代码块.但我刚发现一个我不明白的案例:
#my_hash is a hash in which the keys are strings and the values arrays, but dont think about the specifics fo the code
#if I run my code like this, it works perfectly
my_hash.each do |art|
puts mystring.gsub(art[0]).each {
art[1][rand(art[1].length) -1]
}
end
#but if I use this, it prints "Enumerator"
my_hash.each do |art|
puts mystring.gsub(art[0]).each do
art[1][rand(art[1].length) -1]
end
end
Run Code Online (Sandbox Code Playgroud)
是因为你不能窝对端对吗?我使用的是1.9
puts [1,2,3].map do |x|
x + 1
end.inspect
Run Code Online (Sandbox Code Playgroud)
随着ruby 1.9.2的回归
<Enumerator:0x0000010086be50>
Run Code Online (Sandbox Code Playgroud)
红宝石1.8.7:
# 1
# 2
# 3
Run Code Online (Sandbox Code Playgroud)
分配变量......
x = [1,2,3].map do |x|
x + 1
end.inspect
puts x
Run Code Online (Sandbox Code Playgroud)
[2,3,4]
小胡子块按预期工作:
puts [1,2,3].map { |x| x + 1 }.inspect
Run Code Online (Sandbox Code Playgroud)
[2,3,4]
如果我有课:
class KlassWithSecret
def initialize
@secret = 99
end
end
Run Code Online (Sandbox Code Playgroud)
并运行:
puts KlassWithSecret.new.instance_eval { @secret }
Run Code Online (Sandbox Code Playgroud)
它打印99,但如果我运行:
puts KlassWithSecret.new.instance_eval do
@secret
end
Run Code Online (Sandbox Code Playgroud)
它返回一个错误: `instance_eval': wrong number of arguments (0 for 1..3) (ArgumentError)
为什么我不能使用do/end块instance_eval?
PS我正在使用Ruby 2.1.0.
我对传球有一点疑问.
def a_method(a, b)
a + yield(a, b)
end
Run Code Online (Sandbox Code Playgroud)
这很好用.
k = a_method(1, 2) do |x, y|
(x + y) * 3
end
puts k
Run Code Online (Sandbox Code Playgroud)
但这不起作用.
puts a_method(1, 2) do |x, y|
(x + y) * 3
end
# LocalJumpError: no block given (yield)
Run Code Online (Sandbox Code Playgroud)
有人可以向我解释这个吗?
谢谢.Paolo Perrotta从Metaprogramming Ruby中获取的示例.好书.