Class: Releasy::DSLWrapper
- Inherits:
-
Object
- Object
- Releasy::DSLWrapper
- Defined in:
- lib/releasy/dsl_wrapper.rb
Overview
Wraps an object and redirects public methods to it, to allow for a terse, block-based API.
-
Safer alternative to running Object#instance_eval directly, since protected/private methods and instance variables are not exposed.
-
Less wordy than a system which operates like Object#tap (‘object.tap {|o| o.fish = 5; o.run }`)
A method call, #meth called on the wrapper will try to call #meth or #meth= on the owner, as appropriate.
Instance Attribute Summary collapse
-
#owner ⇒ Object
readonly
Object that the DSLWrapper object is redirecting to.
Instance Method Summary collapse
-
#initialize(owner, &block) ⇒ DSLWrapper
constructor
If passed a block, the DSLWrapper will #instance_eval it automatically.
Constructor Details
#initialize(owner, &block) ⇒ DSLWrapper
If passed a block, the DSLWrapper will #instance_eval it automatically.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/releasy/dsl_wrapper.rb', line 39 def initialize(owner, &block) @owner = owner = class << self; self; end (@owner.public_methods - Object.public_instance_methods).each do |target_method| redirection_method = target_method.to_s.chomp('=').to_sym .class_eval do define_method redirection_method do |*args, &inner_block| if @owner.respond_to? "#{redirection_method}=" and (args.any? or not @owner.respond_to? redirection_method) # Has a setter and we are passing argument(s) or if we haven't got a corresponding getter. @owner.send "#{redirection_method}=", *args, &inner_block elsif @owner.respond_to? redirection_method # We have a getter or general method @owner.send redirection_method, *args, &inner_block else # Should never reach here, but let's be paranoid. raise NoMethodError, "#{owner} does not have a public method, ##{redirection_method}" end end end end instance_eval &block if block_given? end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(meth, *args, &block) ⇒ Object (private)
67 68 69 |
# File 'lib/releasy/dsl_wrapper.rb', line 67 def method_missing(meth, *args, &block) raise NoMethodError, "#{owner} does not have either public method, ##{meth} or ##{meth}=" end |
Instance Attribute Details
#owner ⇒ Object (readonly)
Returns Object that the DSLWrapper object is redirecting to.
29 30 31 |
# File 'lib/releasy/dsl_wrapper.rb', line 29 def owner @owner end |