/liner

A liner for your Ruby classes. Add attribute, inspection, and equality methods for a basic foundation.

Primary LanguageRubyMIT LicenseMIT

Liner

Build Status Coverage Status Gem Version Dependency Status Code Climate

Lay a liner for your Ruby classes. Liner is a lightweight library designed to enhance simple classes with some conveniences and idioms while staying out of your way.

Usage

Setup

You can setup a Liner based class in any of these equivalent ways:

Engine = Liner.new(:layout, :fuel)
class Engine < Liner.new(:layout, :fuel)
end
class Engine
  liner :layout, :fuel
end

Initialization

Your new class comes with an initializer that takes values in the order you defined them.

e = Engine.new('V6', 'gasoline')
# => #<Engine layout="V6", fuel="gasoline">

Or, you can initialize with a hash if you prefer.

e = Engine.new(layout: 'V8', fuel: "gasoline")
# => #<Engine layout="V8", fuel="gasoline">

Attributes

Attribute getters and setters are built in.

e.fuel            # => "gasoline"
e.fuel = "diesel" # => "diesel"

Attributes are accessible via hash style lookup too.

e[:layout]        # => "V8"
e[:layout] = "V6" # => "V6"
e[:foo] = "Bar"   # => ArgumentError: Invalid liner attribute: 'foo'

If you want a full attribute hash, we have that.

e.liner # => { :layout => 'V6', :fuel => 'diesel' }

You can set attributes en masse by sending an array or hash.

e.liner = { layout: 'I4', fuel: 'biofuel' }
e.liner_values = ['I4', 'biofuel']

Inspection

A nice inspection method is always handy.

e.inspect
# => #<Engine layout="V6", fuel="gasoline">

Equality

Normal equality methods are here.

e.eql? Engine.new(layout: 'I4')               # => false
e == Engine.new(layout: 'V6', fuel: 'diesel') # => true

Serialization

JSON serialization is ready after you require it.

require 'json'
e.to_json
# => "{\"layout\":\"V6\",\"fuel\":\"gasoline\"}"

Overriding

Getters/Readers

If you want to customize the way an attribute is read, just override the method like you would any accessor. You can access the raw value through either the instance variable, liner_get, or super.

class Taco < Liner.new(:filling)
  def filling
    if liner_get(:filling) == 'ground beef'
      'Steak'
    elsif @filling == 'unknown fish'
      'Atlantic Cod'
    else
      super()
    end
  end
end

Overridden getters will take precedence for the other features. This is probably desirable, just don't be surprised by it.

taco = Taco.new("ground beef")
# => #<Taco filling="Steak">
taco[:filling] = 'unknown fish'
# => 'unknown fish'
taco.liner
# => {:filling=>"Atlantic Cod"}

Setters/Writers

It's the same scenario for customizing the writer. Set the real value through the instance variable, liner_set, or super.

class Bacon < Liner.new(:is_good)
  def is_good=(good)
    @is_good = true
  end
end

Again, the overridden method takes precendence, even with writers.

generic_bacon = Bacon.new
generic_bacon[:is_good] = false
# => true

Inheritance

Inheritance of Liner classes works like any other Ruby class, but you can tack on extra attributes to child classes if you like.

class Instrument
  liner :key
end

class Guitar < Instrument
  liner :strings
end

Guitar.new('C', 6)
# => #<Guitar key="C", strings=6>

Supported Ruby Versions

This library aims to support and is tested against the following Ruby implementations:

If something doesn't work on one of these versions, it's a bug.

This library may inadvertently work (or seem to work) on other Ruby versions or implementations, however support will only be provided for the implementations listed above.

Installation

Add this line to your application's Gemfile:

gem 'liner'

And then execute:

$ bundle

Or install it yourself as:

$ gem install liner

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request