README.md in sinclair-1.3.0 vs README.md in sinclair-1.3.1
- old
+ new
@@ -6,25 +6,27 @@
[![Gem Version](https://badge.fury.io/rb/sinclair.svg)](https://badge.fury.io/rb/sinclair)
![sinclair](https://raw.githubusercontent.com/darthjee/sinclair/master/sinclair.jpg)
-This gem helps the creation of complex concern with class methods
+This gem helps the creation of complex gems/concerns
+that enables creation of methods on the fly through class
+methods
Yard Documentation
-------------------
-https://www.rubydoc.info/gems/sinclair/1.3.0
+https://www.rubydoc.info/gems/sinclair/1.3.1
Installation
---------------
- Install it
```ruby
gem install sinclair
```
- - Or add Sinclairn to your `Gemfile` and `bundle install`:
+ - Or add Sinclair to your `Gemfile` and `bundle install`:
```ruby
gem 'sinclair'
```
@@ -32,14 +34,16 @@
bundle install sinclair
```
Usage
---------------
-The concern builder can actully be used in two ways, as an stand alone object capable of
-adding methods to your class or by extending it for more complex logics
+# Sinclair
+Sinclair can actully be used in several ways, as an stand alone object capable of
+adding methods to your class on the fly, as a builder inside a class method
+or by extending it for more complex logics
- - Stand Alone usage:
+## Stand Alone usage creating methods on the fly:
```ruby
class Clazz
end
@@ -54,22 +58,82 @@
puts "Twenty => #{instance.twenty}" # Twenty => 20
puts "Eighty => #{instance.eighty}" # Eighty => 80
```
- - Extending the builder
+## Builder in class method:
```ruby
+ class HttpJsonModel
+ attr_reader :json
- class ValidationBuilder < Sinclair
- delegate :expected, to: :options_object
+ class << self
+ def parse(attribute, path: [])
+ builder = Sinclair.new(self)
- def initialize(klass, options={})
- super
+ keys = (path + [attribute]).map(&:to_s)
+
+ builder.add_method(attribute) do
+ keys.inject(hash) { |h, key| h[key] }
+ end
+
+ builder.build
+ end
end
- def add_validation(field)
+ def initialize(json)
+ @json = json
+ end
+
+ def hash
+ @hash ||= JSON.parse(json)
+ end
+ end
+
+ class HttpPerson < HttpJsonModel
+ parse :uid
+ parse :name, path: [:personal_information]
+ parse :age, path: [:personal_information]
+ parse :username, path: [:digital_information]
+ parse :email, path: [:digital_information]
+ end
+
+ json = <<-JSON
+ {
+ "uid": "12sof511",
+ "personal_information":{
+ "name":"Bob",
+ "age": 21
+ },
+ "digital_information":{
+ "username":"lordbob",
+ "email":"lord@bob.com"
+ }
+ }
+ JSON
+
+ person = HttpPerson.new(json)
+
+ person.uid # returns '12sof511'
+ person.name # returns 'Bob'
+ person.age # returns 21
+ person.username # returns 'lordbob'
+ person.email # returns 'lord@bob.com'
+```
+
+## Extending the builder
+
+```ruby
+
+ class ValidationBuilder < Sinclair
+ delegate :expected, to: :options_object
+
+ def initialize(klass, options={})
+ super
+ end
+
+ def add_validation(field)
add_method("#{field}_valid?", "#{field}.is_a?#{expected}")
end
def add_accessors(fields)
klass.send(:attr_accessor, *fields)
@@ -147,14 +211,17 @@
legs: 2
)
invalid_object.valid? # returns false
```
- - Caching the result
- If wanted, the result of the method can be stored in an
- instance variable with the same name
+## Caching the result
+If wanted, the result of the method can be stored in an
+instance variable with the same name.
+When caching, you can cache with type `:full` so that even `nil`
+values are cached
+
```ruby
class MyModel
attr_accessor :base, :expoent
end
@@ -174,9 +241,95 @@
model.expoent = 2
model.cached_power # returns 9
model.expoent = 3
model.cached_power # returns 9 (from cache)
+```
+
+```ruby
+ module DefaultValueable
+ def default_reader(*methods, value:, accept_nil: false)
+ DefaultValueBuilder.new(
+ self, value: value, accept_nil: accept_nil
+ ).add_default_values(*methods)
+ end
+ end
+
+ class DefaultValueBuilder < Sinclair
+ def add_default_values(*methods)
+ default_value = value
+
+ methods.each do |method|
+ add_method(method, cached: cache_type) { default_value }
+ end
+
+ build
+ end
+
+ private
+
+ delegate :accept_nil, :value, to: :options_object
+
+ def cache_type
+ accept_nil ? :full : :simple
+ end
+ end
+
+ class Server
+ extend DefaultValueable
+
+ attr_writer :host, :port
+
+ default_reader :host, value: 'server.com', accept_nil: false
+ default_reader :port, value: 80, accept_nil: true
+
+ def url
+ return "http://#{host}" unless port
+
+ "http://#{host}:#{port}"
+ end
+ end
+
+ server = Server.new
+
+ server.url # returns 'http://server.com:80'
+
+ server.host = 'interstella.com'
+ server.port = 5555
+ server.url # returns 'http://interstella.com:5555'
+
+ server.host = nil
+ server.port = nil
+ server.url # return 'http://server.com'
+```
+
+# Sinclair::Configurable
+
+Configurable is a module that, when used, can add configurations
+to your classes/modules.
+
+Configurations are read-only objects that can only be set using
+the `configurable#configure` method
+
+```ruby
+ class MyConfigurable
+ extend Sinclair::Configurable
+
+ configurable_with :host, :port
+ end
+
+ MyConfigurable.configure do |config|
+ config.host 'interstella.art'
+ config.port 5555
+ end
+
+ MyConfigurable.config.host # returns 'interstella.art'
+ MyConfigurable.config.port # returns 5555
+
+ MyConfigurable.reset_config
+
+ MyConfigurable.config.host # returns nil
+ MyConfigurable.config.port # returns nil
```
RSspec matcher
---------------