1

Prawn gem を使用して PDF を生成するクラスに取り組んでいます。私はいくつかの同様の方法を持っています。それらはすべて同じ行から始まります。コードは次のとおりです。

module PDFGenerator
  class MatchTeamInfo
    include Prawn::View

    def initialize(match)
      @match = match
      @output = Prawn::Document.new page_layout: :landscape
      defaults
      header
      footer
    end

    def render
      @output.render
    end

    def defaults
      @output.instance_exec do
        font_size 16
        text 'hola'
      end
    end

    def header
      @output.instance_exec do
        bounding_box [bounds.left, bounds.top], :width  => bounds.width do
          text "Fulbo", align: :center, size: 32
          stroke_horizontal_rule
          move_down(5)
        end
      end
    end

    def footer
      @output.instance_exec do
        bounding_box [bounds.left, bounds.bottom + 25], :width  => bounds.width do
          stroke_horizontal_rule
          move_down(5)
          text "Tu sitio favorito!", align: :center
        end
      end
    end
  end
end

すべての方法で回避@output.instance_execし、ブロックのようなものを使用する方法はありますか? やってみましたが、うまくいきません。このようなことはできますか?

def apply
  @output.instance_exec do
    yield
  end
end

コード ブロックをどのように定義すればよいですか?

4

2 に答える 2

2

インスタンスdocumentを返すメソッドを定義できます。Prawn::Document

Prawn::View次に、そのドキュメントへのメソッド呼び出しを委任します。次に例を示します。

module PDFGenerator
  class MatchTeamInfo
    include Prawn::View

    def initialize(match)
      @match = match
      defaults
      header
      footer
    end

    def document
      @document ||= Prawn::Document.new page_layout: :landscape
    end

    def defaults
      font_size 16
      text 'hola'
    end

    def header
      bounding_box [bounds.left, bounds.top], :width  => bounds.width do
        text "Fulbo", align: :center, size: 32
        stroke_horizontal_rule
        move_down(5)
      end
    end

    def footer
      bounding_box [bounds.left, bounds.bottom + 25], :width  => bounds.width do
        stroke_horizontal_rule
        move_down(5)
        text "Tu sitio favorito!", align: :center
      end
    end
  end
end

使用例:

pdf = PDFGenerator::MatchTeamInfo.new(nil)
pdf.save_as('team_info.pdf')

出力: (PNG に変換)

team_info.pdf

于 2015-09-24T07:42:49.427 に答える
2

まず、すべてのヘルパー メソッドがlambdaインスタンスを返すようにする必要があります。

def defaults
  lambda do
    font_size 16
    text 'hola'
  end
end

これで、ヘルパーから返されたラムダを に渡すことができますinstance_exec。「これは通常のパラメータではなくコード ブロックです」と認めるために、ラムダの前にアンパサンドを付けます。

def apply
  #                     ⇓ NB! codeblock is passed!
  @output.instance_exec &defaults
end

コードブロックを に渡したい場合はapply、 に再度渡す必要がありますinstance_exec。残念ながら、キーワードを使用して再渡す方法はわかりませんyieldが、ここにトリックがあります。Proc.new指定されたコードブロックで呼び出されたメソッド内でパラメーターなしで呼び出され、このコードブロックでインスタンス化されるので、ここに行きます:

def apply
  raise 'Codeblock expected' unless block_given?
  @output.instance_exec &Proc.new
end
于 2015-09-24T05:42:58.130 に答える