Class: Decor::Base

Inherits:
Struct
  • Object
show all
Defined in:
lib/decor.rb

Overview

The basis of our version wrapper.

Whenever a version is specified using ‘Decor#for`, it is wrapped in a decoration that makes it behave like the specified version.

This decoration proxies all calls it doesn’t define itself to the original object (the ‘target`).

‘options` provides context, which are treated as instance methods for the versions. See `for` for details.

Instance Attribute Summary collapse

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object

This proxies calls to the target if we don’t define it explicitly.

However, if the ‘options` context defines a key that matches the `method` name, we return that value instead.



237
238
239
240
241
# File 'lib/decor.rb', line 237

def method_missing(method, *args, &block)
  return options[method]                    if options.key?(method)
  return target.send(method, *args, &block) if respond_to?(method)
  super
end

Instance Attribute Details

#optionsObject

This provides additional context to the versions specified. Useful for making external resources accessible, overriding accessors, etc.

Ensures ‘options` is an empty Hash even when not set.



230
231
232
# File 'lib/decor.rb', line 230

def options
  @options
end

#targetObject

Returns the value of attribute target

Returns:

  • (Object)

    the current value of target



230
231
232
# File 'lib/decor.rb', line 230

def target
  @target
end

#versionObject

Returns the value of attribute version

Returns:

  • (Object)

    the current value of version



230
231
232
# File 'lib/decor.rb', line 230

def version
  @version
end

Instance Method Details

#for(*args) ⇒ Object

If ‘for` is called on an object that is already wrapped by a version, we return the `target` with a new version wrapper. This allows for an object to change its version representation at will.

For example:

class Model
  include Decor

  version "v1" do
    def original?
      true
    end
  end

  version "v2" do
    def original?
      false
    end
  end
end

model = Model.new.for("v1")
model.original? #=> true

model = model.for("v2")
model.original? #=> false


299
300
301
# File 'lib/decor.rb', line 299

def for(*args)
  target.for(*args)
end

#respond_to?(method) ⇒ Boolean

We can handle the method call if we have a match in the ‘options` context or if our `target` object responds to the method.

For example:

class Model
  include Decor

  version "v1" do
    def foo
    end
  end

  def baz
  end

end

model = Model.new.for("v1", :bar => true)
model.respond_to?(:foo)   #=> true # in version
model.respond_to?(:bar)   #=> true # in context
model.respond_to?(:baz)   #=> true # on target
model.respond_to?(:quux)  #=> false

Returns:

  • (Boolean)


267
268
269
# File 'lib/decor.rb', line 267

def respond_to?(method)
  super or options.key?(method) or target.respond_to?(method)
end