Class: PatternPatch::Renderer
- Inherits:
-
Object
- Object
- PatternPatch::Renderer
- Defined in:
- lib/pattern_patch/renderer.rb
Overview
Provides a fairly clean binding for resolving locals in Ruby < 2.5. All locals become method calls in the binding passed to ERB. A separate class (instead of a Module, e.g.) means minimal clutter in the set of methods available to the binding.
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize(text, safe_level = nil, trim_mode = nil) ⇒ Renderer
constructor
A new instance of Renderer.
- #method_missing(method_sym, *args, &block) ⇒ Object
-
#render(locals_or_binding = {}) ⇒ Object
Render an ERB template with a binding or locals.
Constructor Details
#initialize(text, safe_level = nil, trim_mode = nil) ⇒ Renderer
18 19 20 21 22 23 24 25 |
# File 'lib/pattern_patch/renderer.rb', line 18 def initialize(text, safe_level = nil, trim_mode = nil) if self.class.is_ruby3? @template = ERB.new text, trim_mode: trim_mode else @template = ERB.new text, safe_level, trim_mode end @locals = {} end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method_sym, *args, &block) ⇒ Object
56 57 58 59 60 |
# File 'lib/pattern_patch/renderer.rb', line 56 def method_missing(method_sym, *args, &block) return super unless @locals.key?(method_sym) @locals[method_sym] end |
Class Method Details
.is_ruby3? ⇒ Boolean
11 12 13 14 15 |
# File 'lib/pattern_patch/renderer.rb', line 11 def is_ruby3? version = Gem::Version.new RUBY_VERSION requirement = Gem::Requirement.new '>= 3' requirement =~ version end |
Instance Method Details
#render(locals_or_binding = {}) ⇒ Object
Render an ERB template with a binding or locals.
renderer = Renderer.new template_text
result = renderer.render binding
result = renderer.render a: 'foo', b: 1
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/pattern_patch/renderer.rb', line 34 def render(locals_or_binding = {}) # Pass a Binding this way. return @template.result(locals_or_binding) unless locals_or_binding.kind_of?(Hash) @locals = locals_or_binding.symbolize_keys # Any local that corresponds to a method name in this class is invalid # because it cannot trigger method_missing. The same goes for # locals_or_binding, the only local variable. # Avoid new methods and local variables, which will be visible in the binding. # Could validate only for Ruby < 2.5, but better to be consistent. if @locals.any? { |l| respond_to?(l) || l == :locals_or_binding } raise ArgumentError, "Invalid locals: #{@locals.select { |l| respond_to?(l) || l == :locals_or_binding }.map(&:to_str).join ', '}" end if @template.respond_to? :result_with_hash # ERB#result_with_hash requires Ruby 2.5. @template.result_with_hash locals_or_binding else @template.result binding end end |