3

自己学習用のシンプルで小さなテンプレート パーサーを作成しようとしています。

「モジュール式」のものを構築してデータを共有するにはどうすればよいですか? データは外部からアクセスできる必要はありません。それは単なる内部データです。ここに私が持っているものがあります:

# template_parser.rb
module TemplateParser
  attr_accessor :html
  attr_accessor :test_value

  class Base
    def initialize(html)
      @html = html
      @test_value = "foo"
    end

    def parse!
      @html.css('a').each do |node|
        ::TemplateParser::Tag:ATag.substitute! node
      end
    end
  end
end

# template_parser/tag/a_tag.rb
module TemplateParser
  module Tag
    class ATag
      def self.substitute!(node)
        # I want to access +test_value+ from +TemplateParser+
        node = @test_value # => nil
      end
    end
  end
end

Phrogzのコメントに基づいて編集
私は現在、次のようなことを考えています:

p = TemplateParser.new(html, *args) # or TemplateParser::Base.new(html, *args)
p.append_css(file_or_string)
parsed_html = p.parse!

パーサーは非一般的な問題を解決する必要があり、移植性がないため、公開されたメソッドはあまりあるべきではありません。少なくともこの初期段階ではありません。私が試したことは、ノコギリから構造について少し覗くことです.

4

1 に答える 1

2

あなたが与えたサンプルコードでは、次のようにコンポジションを使用してのインスタンスをメソッドに渡すことをお勧めしTemplateParser::Baseますparse!

# in TemplateParser::Base#parse!
::TemplateParser::Tag::ATag.substitute! node, self

# TemplateParser::Tag::ATag
def self.substitute!(node, obj)
  node = obj.test_value
end

attr_accessorこれを機能させるには、呼び出しをBaseクラスに移動する必要もあります。

module TemplateParser
  class Base
    attr_accessor :html
    attr_accessor :test_value
    # ...
  end
end

私が今考えることができるアクセスの他の方法は、それが別のクラスインスタンスの属性にアクセスしようとしているクラスメソッドであるtest_valueという事実を考えると、かなり複雑になります。parse!

上記は、インスタンス@test_valueごとに一意である必要があると想定しています。TemplateParser::Baseそうでない場合は、クラスまたはモジュールのインスタンス変数を使用してプロセスを簡素化できます。

module TemplateParser
  class Base
    @test_value = "foo"
    class << self
      attr_accessor :test_value
    end
    # ...
  end
end

# OR

module TemplateParser
  @test_value = "foo"
  class << self
    attr_accessor :test_value
  end
  class Base
    # ...
  end
end

次に、実装に応じてTemplateParser::Base.test_valueORで値を設定または取得します。TemplateParser.test_value

また、おそらく明白なことを述べるために、ここに含めた疑似コードが実際のアプリケーションコードを正確に反映していないと仮定しています。もしそうなら、そのsubstitute!メソッドは単純な割り当てを達成するための非常にラウンドアバウトな方法です。node = test_value内部で使用するだけTemplateParser::Base#parse!で、往復をスキップできます。あなたはこれを知っていると確信していますが、少なくとも言及する価値があるように思われました...

于 2012-05-01T20:36:32.993 に答える