[英]Understanding scope in ruby block
我正在使用Prawn gem編寫PDF。 我已經開始寫PDF了,但是我不明白如何正確使用數據。 我有:
def download
@bid = Bid.find(params[:bid_id])
@title = @bid.bid_title.gsub(/\s+/, "")
Prawn::Document.generate("#{@title}.pdf") do
text @bid.client_name
end
end
在我添加文字的地方,出價為零。 如何在下面的代碼塊中使用之前創建的@bid
?
深入研究源代碼以了解所有魔術的工作原理通常很有用。
如果考慮Prawn源代碼 ,我們可以看到在self.generate(filename, options = {}, &block)
我們的塊被傳輸到Prawn :: Document.new方法。 因此,我們將考慮Prawn :: Document的initialize
方法。 在那里,我們可以看到以下代碼:
if block
block.arity < 1 ? instance_eval(&block) : block[self]
end
#arity is a number of block arguments.
# block[self] is a block.call(self)
如果我們簡化Prawn源代碼,我們可以模擬這種情況以更好地理解它:
module Prawn
class Document
def self.generate(filename, &block)
block.arity < 1 ? instance_eval(&block) : block[self]
end
end
end
class A
def initialize
@a = 1
end
def foo
qwe = 1
Prawn::Document.generate("foobar") do
p @a
p qwe
p instance_variables
end
end
end
A.new.foo
# Output:
nil # @a
1 # qwe
[] # there is no instance_variables
但是,如果我們為塊提供一個參數,則將調用generate中的另一個條件(block [self]而不是instance_eval):
module Prawn
class Document
def self.generate(filename, &block)
block.arity < 1 ? instance_eval(&block) : block[self]
end
end
end
class A
def initialize
@a = 1
end
def foo
qwe = 1
Prawn::Document.generate("foobar") do |whatever|
p @a
p qwe
p instance_variables
end
end
end
A.new.foo
# Output
1 # @a
1 # qwe
[:@a] # instance_variables
因此,在您的情況下,我認為此代碼將起作用:
def download
@bid = Bid.find(params[:bid_id])
@title = @bid.bid_title.gsub(/\s+/, "")
Prawn::Document.generate("#{@title}.pdf") do |ignored|
text @bid.client_name
end
end
要么
def download
bid = Bid.find(params[:bid_id])
title = @bid.bid_title.gsub(/\s+/, "")
Prawn::Document.generate("#{title}.pdf") do
text bid.client_name
end
end
您的問題是Prawn::Document.generate
在Prawn :: Document實例的上下文中評估該塊。 這意味着該塊中的實例變量將被解析為Prawn :: Document對象的實例變量,因為它在該塊的上下文中是self
。
為此,請使用局部變量代替實例變量(或在實例變量之外)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.