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', <<-RUBY, args: context_name)
				self.instance_eval do
					#{src}
				end
			RUBY
		when :string
			src.to_s
		else 
			warn "wrap meth #{warn} not understood, defaulting to String"
			src
		end
	return eval(to_eval, bind, "(wrap #{@filename})")
end

#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