Module: DR::Eruby::EngineHelper

Included in:
Template
Defined in:
lib/dr/base/eruby.rb

Instance Method Summary collapse

Instance Method Details

#compile(wrap: :proc, bind: BindingHelper.empty_binding, locals: nil, pre: nil, post: nil, context_name: '_context') ⇒ Object

Note that when the result is not used afterwards via "instance_eval" then the Klass of binding is important when src has 'def foo...' If set, locals should be an array of variable names



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/dr/base/eruby.rb', line 63

def compile(wrap: :proc, bind: BindingHelper.empty_binding, locals: nil, pre: nil, post: nil, context_name: '_context')
  src=@src
  src=BindingHelper.local_extraction(locals, context_name: context_name)+src if locals
  src=pre+"\n"+src if pre
  src<< post+"\n" if post
  to_eval=case wrap
    when :eval; @src
    when :lambda; "lambda { |#{context_name}| #{src} }"
    when :proc; "Proc.new { |#{context_name}| #{src} }"
    when :module; "Module.new { |#{context_name}| #{src} }"
    when :unbound
      #wrapping in a method allows us to pass a block to a code
      #calling yield
      require 'dr/ruby_ext/meta_ext'
      return Meta.get_unbound_evalmethod('eruby', src, args: context_name)
    when :unbound_instance
      #here we wrap in a method that the calls instance_eval
      require 'dr/ruby_ext/meta_ext'
      return Meta.get_unbound_evalmethod('eruby', "        self.instance_eval do\n          \#{src}\n        end\n      RUBY\n    when :string\n      src.to_s\n    else \n      warn \"wrap meth \#{warn} not understood, defaulting to String\"\n      src\n    end\n  return eval(to_eval, bind, \"(wrap \#{@filename})\")\nend\n", args: context_name)

#def_method(object, method_name, filename = nil) ⇒ Object

if object is an Class or Module then define instance method to it, else define singleton method to it.



111
112
113
114
115
# File 'lib/dr/base/eruby.rb', line 111

def def_method(object, method_name, filename=nil)
  m = object.is_a?(Module) ? :module_eval : :instance_eval
  object.__send__(m, "def #{method_name}; #{@src}; end", filename || @filename || '(eruby)')
  #erb.rb: src = self.src.sub(/^(?!#|$)/) {"def #{methodname}\n"} << "\nend\n" #This pattern insert the 'def' after lines with leading comments
end

#evaluate(_context = Context.new, compile: {}, **opts, &b) ⇒ Object

by default invoke context.instance_eval(@src)



96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/dr/base/eruby.rb', line 96

def evaluate(_context=Context.new, compile: {}, **opts, &b)
  #I prefer to pass context as a keyword, but we allow to pass it as
  #an argument to respect erubis's api
  _context=opts[:context] if opts.key?(:context)
  _context = Context.new(_context) if _context.is_a?(Hash)
  vars=opts[:vars]
  compile[:locals]||=vars.keys if vars
  #to pass a block we need to wrap in a method
  compile[:wrap]||=:unbound_instance if b
  _proc=compile(**compile)
  Eruby.evaluate(_proc, context: _context, **opts, &b)
end

#result(_binding_or_hash = BindingHelper.empty_binding) ⇒ Object

Stolen from erubis eval(@src) with binding object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/dr/base/eruby.rb', line 40

def result(_binding_or_hash=BindingHelper.empty_binding)
  _arg = _binding_or_hash
  if _arg.is_a?(Hash)
    _b=BindingHelper.add_variables(_arg, BindingHelper.empty_binding)
  elsif _arg.is_a?(Binding)
    _b = _arg
  elsif _arg.nil?
    _b = binding
  else
    raise ArgumentError.new("#{self.class.name}#result(): argument should be Binding or Hash but passed #{_arg.class.name} object.")
  end
  return eval(@src, _b, (@filename || '(eruby'))
  #erb.rb:
  #  if @safe_level
  #  proc {
  #     $SAFE = @safe_level
  #     eval(@src, b, (@filename || '(erb)'), @lineno)
  #  }.call
end