class Bless::Blesser

Attributes

blessee[R]
blessee_code[R]
blessee_owner[R]
code[R]
context[R]
invoker[R]
klass[R]
object[R]

Public Class Methods

bless(object, klass, context, invoker) click to toggle source
# File lib/bless.rb, line 8
def self.bless(object, klass, context, invoker)
  assert_kernel_ancestor_on(object)
  new(object, klass, context, invoker).bless
end
new(object, klass, context, invoker) click to toggle source
# File lib/bless.rb, line 25
def initialize(object, klass, context, invoker)
  @object = object
  @context = context
  @invoker = invoker
  @klass = determine_target_class(klass)
  @code = code_for_invoker
  @blessee_code = extract_blessee_code
  @blessee, @blessee_owner = blessee_and_owner
end

Private Class Methods

assert_kernel_ancestor_on(object) click to toggle source
# File lib/bless.rb, line 35
def self.assert_kernel_ancestor_on(object)
  object.class.ancestors.include?(Kernel)
rescue NoMethodError => e
  raise CannotBlessSimpletons.new
end

Public Instance Methods

bless() click to toggle source
# File lib/bless.rb, line 13
def bless
  if blessee_writeable?
    convert_or_set_blessee_in_context
  else
    convert_or_instantiate
  end
end

Private Instance Methods

assignable_variables_for_context() click to toggle source
# File lib/bless.rb, line 110
def assignable_variables_for_context
  context.eval('local_variables + instance_variables')
end
blessee_and_owner() click to toggle source
# File lib/bless.rb, line 65
def blessee_and_owner
  blessee_elements = blessee_code.split('.')
  [blessee_elements.pop, blessee_elements.join('.')]
end
blessee_assignable?() click to toggle source
# File lib/bless.rb, line 106
def blessee_assignable?
  context.eval "#{blessee_owner}.respond_to?('#{blessee}=')"
end
blessee_writeable?() click to toggle source
# File lib/bless.rb, line 98
def blessee_writeable?
  if !blessee_owner.empty?
    blessee_assignable?
  else
    assignable_variables_for_context.include?(blessee.to_sym)
  end
end
code_for_invoker() click to toggle source
# File lib/bless.rb, line 45
def code_for_invoker
  file, line = invoker.split(':')
  IO.readlines(file)[line.to_i - 1].strip
end
code_regex() click to toggle source
# File lib/bless.rb, line 55
def code_regex
  /
    bless
    (\(\s*|\s+)     # optional opening parens followed by optional whitespace OR mandatory whitespace
    (?<var>[^,\s]+) # extract variable name
    (\s*,\s*.+)?    # optional whitespace, comma, optional whitespace, whatever (all optional)
    \)?             # optional closing parens
  /x
end
convert_blessee_in_context() click to toggle source
# File lib/bless.rb, line 82
def convert_blessee_in_context
  context.eval("#{blessee_code} = send('#{klass.name}', #{blessee_code})")
end
convert_or_instantiate() click to toggle source
# File lib/bless.rb, line 90
def convert_or_instantiate
  if convertable_object?
    send(klass.name, object)
  else
    klass.new
  end
end
convert_or_set_blessee_in_context() click to toggle source
# File lib/bless.rb, line 74
def convert_or_set_blessee_in_context
  if convertable_object?
    convert_blessee_in_context
  else
    set_blessee_in_context
  end
end
convertable_object?() click to toggle source
# File lib/bless.rb, line 70
def convertable_object?
  Kernel.methods.include?(klass.name.to_sym)
end
determine_target_class(klass) click to toggle source
# File lib/bless.rb, line 41
def determine_target_class(klass)
  klass || context.eval('self.class')
end
extract_blessee_code() click to toggle source
# File lib/bless.rb, line 50
def extract_blessee_code
  match_data = code.match code_regex
  match_data[:var] if match_data
end
set_blessee_in_context() click to toggle source
# File lib/bless.rb, line 86
def set_blessee_in_context
  context.eval("#{blessee_code} = #{klass}.new")
end