0

Rails コントローラー内にいて、ブロック内のインスタンス変数にアクセスしようとしています。これにより、「Nil のメソッド field1 がありません」というエラーが表示されます。

Prawn::Document.generate("hello.pdf") do
  @model.field1
end

ただし、これを行うと、次のように機能します。

my_model = @model
Prawn::Document.generate("hello.pdf") do
  my_model.field1
end

これは、ブロック内の ActiveRecord アクセサーまたはインスタンス変数と関係がありますか?

4

2 に答える 2

3

この種の問題は、ブロックが異なるコンテキストで (通常はinstance_eval. それでは、コードを確認しましょう。

#lib/prawn/document.rb: Document#initialize    
if block
  block.arity < 1 ? instance_eval(&block) : block[self]
end

がありinstance_eval、解決策も表示されます。ドキュメントを引数として受け入れるブロックを渡すと、通常どおりインスタンス変数にアクセスできるようになります。

Prawn::Document.generate("hello.pdf") do |doc|
  @my_model.field1
end
于 2011-11-12T21:23:21.503 に答える
1

これは、ブロック内のコードが Prawn::Document オブジェクトのコンテキストで実行されるためです。このコードの中に入りましょう:

module Prawn
  class Document
    def self.generate(filename,options={},&block)
      pdf = new(options,&block)
      pdf.render_file(filename)
    end

    def initialize(options={},&block)
      if block
        block.arity < 1 ? instance_eval(&block) : block[self]
      end
    end
  end
end

ご覧のとおり、はobject asblockで実行されます。のインスタンス変数として @model を見つけようとしますが、これを実行できず、 を返します。ローカル変数を使用すると、クロージャーの助けが得られ、コードが適切に機能しますDocumentselfselfnilmodel

于 2011-11-12T21:25:22.397 に答える