Liner
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 (to_h
and to_hash
also work).
e.liner # => { :layout => 'V6', :fuel => 'diesel' }
Inspection
It's always nice not to have to set up inspection (note that to_s
is the same
here).
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,
read_attribute
, or super
.
class Taco < Liner.new(:filling)
def filling
if read_liner(: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, write_attribute
, 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>
Installation
Add this line to your application's Gemfile:
gem 'liner'
And then execute:
$ bundle
Or install it yourself as:
$ gem install liner
Contributing
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request