簡體   English   中英

了解紅寶石塊的范圍

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM