kschiess / parslet

A small PEG based parser library. See the Hacking page in the Wiki as well.
kschiess.github.com/parslet
MIT License
809 stars 95 forks source link

allow to call transform's method from the given block #225

Open taichi-ishitani opened 1 year ago

taichi-ishitani commented 1 year ago

I think defining helper methods is good solution to simplify complex transform logics like we do that for the parser class. However we cannot do that; for exmaple:

# test.rb
require 'parslet'

class Transform < Parslet::Transform
  rule(a: simple(:a)) { foo(a) }
  def foo(a); a.to_sym; end
end

p Transform.new.apply({ a: 'a' })
$ ruby ../../temp/test.rb
../../temp/test.rb:4:in `block in <class:Transform>': undefined method `foo' for #<Parslet::Context:0x00007f0be690ece8 @a="a"> (NoMethodError)

  rule(a: simple(:a)) { foo(a) }
                        ^^^
Did you mean?  for
        from /opt/rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/parslet-2.0.0/lib/parslet/transform.rb:217:in `instance_eval'
        from /opt/rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/parslet-2.0.0/lib/parslet/transform.rb:217:in `call_on_match'
        from /opt/rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/parslet-2.0.0/lib/parslet/transform.rb:235:in `block in transform_elt'
        from /opt/rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/parslet-2.0.0/lib/parslet/transform.rb:232:in `each'
        from /opt/rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/parslet-2.0.0/lib/parslet/transform.rb:232:in `transform_elt'
        from /opt/rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/parslet-2.0.0/lib/parslet/transform.rb:185:in `apply'
        from ../../temp/test.rb:8:in `<main>'

This PR is to allow to call methods defined in the transform class from the given transform block.