Skip to content

Delegator pattern in Ruby without object schizophrenia. Because Object#extend at runtime is evil.

License

Notifications You must be signed in to change notification settings

RichOrElse/type-wrapper

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TypeWrapper

Gem Version Build Status

Delegator pattern in Ruby without object schizophrenia. Because Object#extend at runtime is evil.

Installation

Add this line to your application's Gemfile:

gem 'type_wrapper'

And then execute:

$ bundle

Or install it yourself as:

$ gem install type_wrapper

Usage

TypeWrapper

Construct a delegator class using square brackets '[]' method with type as the first argument followed by mixins.

module ToArray
  def to_a
    [self]
  end
end

module ToString
  def to_s
    "#{self}"
  end
end

Person = Struct.new(:name)

PersonPresenter = TypeWrapper[Person, ToArray, ToString]

peter = PersonPresenter.new(Person.new('Peter'))
peter.to_a

TypeWrapper::Module

Define a block with the 'new' method and pass the 'mod' parameter to 'using' keyword.

AwesomeSinging = TypeWrapper::Module.new do |mod| using mod
  def sing
    "#{name} sings #{song}"
  end

  def song
    "Everything is AWESOME!!!"
  end
end

Lego = Struct.new(:name)

using AwesomeSinging[Lego]
Lego.new("Emmet").sing

TypeWrapper::Forwarding

Creates a Module that delegates Refinements methods (forwarding) to a target object.

Lego = Struct.new(:name)

module LoudSpeaking
  def speak(words)
    "#{name}: #{words.upcase}!!!"
  end

  def say(words)
    "#{name}: #{words.upcase}!!!"
  end
end

# Refinements
module LoudSpeakingLego
  refine Lego do
    include LoudSpeaking
  end
end

# target: speaker
class LoudLego < Struct.new(:speaker)
  include TypeWrapper::Forwarding[LoudSpeakingLego, :speak, :say, to: :speaker]
end

batman = Lego.new('Batman')
loud_lego = LoudLego.new(batman)
loud_lego.speak("I'm Batman") # => "Batman: I'M BATMAN!!!"

Pros

Cons

  • Must use TypeWrapper::Module to allow procedural code in mixins.
  • Three (3) times slower than calling class method. See benchmark.
  • Methods applied with Object#extend takes precedence over Mixin methods.

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake test to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/RichOrElse/type_wrapper.

License

The gem is available as open source under the terms of the MIT License.

About

Delegator pattern in Ruby without object schizophrenia. Because Object#extend at runtime is evil.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published