module Rack::Component::Methods

@example If you don't want to subclass, you can extend Rack::Component::Methods instead.

class POROGreeter
  extend Rack::Component::Methods
  render { "Hi, #{env[:name]" }
end

Public Class Methods

extended(base) click to toggle source
# File lib/rack/component.rb, line 21
def self.extended(base)
  base.include(InstanceMethods)
end

Public Instance Methods

call(env = {}, &children) click to toggle source
# File lib/rack/component.rb, line 29
def call(env = {}, &children)
  new(env).render(&children)
end
render(opts = {}) click to toggle source
# File lib/rack/component.rb, line 25
def render(opts = {})
  block_given? ? configure_block(Proc.new) : configure_template(opts)
end

Private Instance Methods

configure_block(block) click to toggle source

:reek: TooManyStatements :reek: DuplicateMethodCall

# File lib/rack/component.rb, line 58
def configure_block(block)
  # Convert the block to an instance method, because instance_exec
  # doesn't allow passing an &child param, and because it's faster.
  define_method :_rc_render, &block
  private :_rc_render

  # Now that the block is a method, it must be called with the correct
  # number of arguments. Ruby's +arity+ method is unreliable when keyword
  # args are involved, so we count arity by hand.
  arity = block.parameters.reject { |type, _| type == :block }.length

  # Reek hates this DuplicateMethodCall, but fixing it would mean checking
  # arity at runtime, rather than when the render macro is called.
  if arity.zero?
    define_method(:render) { |&child| _rc_render(&child) }
  else
    define_method(:render) { |&child| _rc_render(env, &child) }
  end
end
configure_template(options) click to toggle source
# File lib/rack/component.rb, line 78
def configure_template(options)
  renderer = Renderer.new(options)
  define_method(:render) { |&child| renderer.call(self, &child) }
end