Module: Parsby::Combinators::ModuleMethods

Included in:
Parsby::Combinators
Defined in:
lib/parsby/combinators.rb

Instance Method Summary collapse

Instance Method Details

#define_combinator(name, wrap: true, &b) ⇒ Object

The only reason to use this over regular def syntax is to get automatic labels. For combinators defined with this, you’ll get labels that resemble the corresponding ruby expression.



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/parsby/combinators.rb', line 9

def define_combinator(name, wrap: true, &b)
  # Convert block to method. This is necessary not only to convert
  # the proc to something that'll verify arity, but also to get
  # super() in b to work.
  define_method(name, &b)
  m = if defined? instance_method
    instance_method name
  else
    # self is probably main
    method(name).unbind
  end

  # Lambda used to access private module method from instance method.
  inspectable_labels_lambda = lambda {|x| inspectable_labels(x) }

  define_method name do |*args, &b2|
    inspected_args = inspectable_labels_lambda.call(args).map(&:inspect)
    label = name.to_s
    label += "(#{inspected_args.join(", ")})" unless inspected_args.empty?
    # Wrap in new parser so we don't overwrite another automatic
    # label.
    p = m.bind(self).call(*args, &b2)
    if wrap
      Parsby.new(label) {|c| p.parse c }
    else
      p % label
    end
  end
end