我正在学习Ruby on Rails,因为我正在处理概念,我也正在处理语法,当你开始使用RoR时这有点奇怪。每个Michael Hartl的教程
当散列是函数调用中的最后一个参数时,大括号 是可选的
我理解这一点,但是当作者提到回调时,这行代码出现了:
category = []
columns = []
read = open('file1.txt', 'r')
for line in read:
fields = line.split('|')
columns.append(fields)
category.append(int(fields[4]))
category = sorted(set(category))
print(category)
for line in columns:
print(line)
out = open('fileout.txt', 'w')
out.write('column 1|column 2|column 6|column 7|')
for val in category:
out.write('column3_{0}|'.format(val))
for val in category:
out.write('column4_{0}|'.format(val))
out.write('\n')
for line in columns:
out.write('{0}|{1}|{2}|{3}|'.format(line[0], line[1], line[5], line[6].rstrip()))
for val in category:
if int(line[4]) == val:
out.write('{0}|'.format(line[2]))
else:
out.write(' |')
for val in category:
if int(line[4]) == val:
out.write('{0}|'.format(line[3]))
else:
out.write(' |')
out.write('\n')
我理解before_save是方法。有人可以为我打破这个论点,为什么你不能放弃大括号?
答案 0 :(得分:4)
您的代码中没有哈希值。你正在看的是一个块,这是一种匿名函数。 Ruby有两种不同的块语法。这段代码:
before_save { self.email = email.downcase }
...相当于这段代码:
before_save do
self.email = email.downcase
end
通常,花括号用于单行,do ... end
用于多行。在任何一种情况下,你正在做的是定义一个"块"代码然后将其作为参数传递给before_save
方法。这允许Rails将该代码块存储在变量中并稍后执行,或者将代码传递给其他方法。上述两个例子大致相当于:
my_block = proc do
self.email = email.downcase
end
before_save(&my_block)
块参数很特殊。一个方法只能有一个块参数,它必须是最后一个参数。在最后一段代码中,我使用proc
(Proc.new
的快捷方式)实际上将块保存到变量,然后将该变量传递给before_save
作为一个论点。 &
告诉Ruby它应该将Proc作为before_save
的块参数。
但是,有一些语法陷阱会突然出现。例如,这是有效的:
[ "two", "three" ].reduce "one" do |memo, item|
memo << item
end
# => "onetwothree"
但这不是:
[ "two", "three" ].reduce "one" {|memo, item| memo << item }
# => SyntaxError: unexpected '{', expecting end-of-input
当你使用大括号语法并且有参数(如上面的"one"
)时,你必须使用括号:
[ "two", "three" ].reduce("one") {|memo, item| memo << item }
# => "onetwothree"
除了块和Proc之外,Ruby还有一种特殊的Proc,叫做lambda。您将在一些Rails文档中看到lambdas,它们看起来像这样:
scope :published, -> { where(published: true) }
这是此的捷径:
scope :published, lambda { where(published: true) }
# ...or...
scope :published, lambda do
where(published: true)
end
......这些都等同于:
my_lambda = ->{ where(published: true) }
scope :published, my_lambda
请注意,第二行&
之前没有my_lambda
。这是因为Rails&#39;开发人员已经选择让scope
将lambda作为常规参数 - 而不是它的块参数 - 我认为这主要是因为它不必是最后一个参数。
块,触发器和lambdas之间的区别超出了这个答案的范围,有时甚至是微妙的,但它具有很好的知识。我推荐这篇文章以获取更多信息:https://rubymonk.com/learning/books/4-ruby-primer-ascent/chapters/18-blocks/lessons/64-blocks-procs-lambdas
答案 1 :(得分:1)
你指的是作为参数传递的花括号是一个块 传递给回调的块通过instance_eval执行,因此其范围是记录本身。