Import Upstream version 0.1.0

parents
*.gem
*.rbc
/.config
/coverage/
/InstalledFiles
/pkg/
/spec/reports/
/spec/examples.txt
/test/tmp/
/test/version_tmp/
/tmp/
# Used by dotenv library to load environment variables.
# .env
## Specific to RubyMotion:
.dat*
.repl_history
build/
*.bridgesupport
build-iPhoneOS/
build-iPhoneSimulator/
## Specific to RubyMotion (use of CocoaPods):
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
# vendor/Pods/
## Documentation cache and generated files:
/.yardoc/
/_yardoc/
/doc/
/rdoc/
## Environment normalization:
/.bundle/
/vendor/bundle
/lib/bundler/man/
# for a library or gem, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# Gemfile.lock
# .ruby-version
# .ruby-gemset
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
.rvmrc
rvm:
- 1.9.3
- 2.0.0
- 2.1
- 2.2
- 2.3.1
- 2.4.0
- jruby-19mode
- jruby
before_install:
- gem install bundler
# 0.1.0
* Introduce `Declarative::Option` and `Declarative::Options` as a replacement for `Uber::Options::Value` and `Uber::Options`.
source 'https://rubygems.org'
# Specify your gem's dependencies in uber.gemspec
gemspec
gem "benchmark-ips"
gem "minitest-line"
gem "rake"
PATH
remote: .
specs:
declarative-option (0.1.0)
GEM
remote: https://rubygems.org/
specs:
benchmark-ips (2.7.2)
minitest (5.10.1)
minitest-line (0.6.3)
minitest (~> 5.0)
rake (12.0.0)
PLATFORMS
ruby
DEPENDENCIES
benchmark-ips
declarative-option!
minitest
minitest-line
rake
BUNDLED WITH
1.12.5
Copyright (c) 2012 Nick Sutterer
MIT License
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
# Declarative::Option
_Dynamic options to evaluate at runtime._
## Installation
[![Gem Version](https://badge.fury.io/rb/mega-option.svg)](http://badge.fury.io/rb/mega-option)
Add this line to your application's Gemfile:
```ruby
gem 'mega-options'
```
Runs with Ruby >= 1.9.3.
# Option
Pass any value to `Option`, it will wrap it accordingly and make it executable, so you can call the value at runtime to evaluate it.
It works with static values.
```ruby
option = Declarative::Option(false)
option.(context, *args) #=> false
```
When passing in a `:symbol`, this will be treated as a method that's called on the context. The context is the first argument to `Option#call`.
```ruby
option = Declarative::Option(:object_id)
option.(Object.new, *args) #=> 2354383
```
Same with objects marked with `Callable`.
```ruby
class CallMe
include Declarative::Callable
def call(context, *args)
puts "hello!"
end
end
option = Declarative::Option(Callable.new) #=> "hello!"
```
And of course, with lambdas.
```ruby
option = Declarative::Option( ->(context, *args) { puts "yo!" } )
option.(context) #=> yo!
```
All `call` arguments behind the first are passed to the wrapped value.
# License
Copyright (c) 2017 by Nick Sutterer <apotonick@gmail.com>
Uber is released under the [MIT License](http://www.opensource.org/licenses/MIT).
#!/usr/bin/env rake
require "bundler/gem_tasks"
require 'rake/testtask'
desc 'Test the representable gem.'
task :default => :test
Rake::TestTask.new(:test) do |test|
test.libs << 'test'
test.test_files = FileList['test/*_test.rb']
test.verbose = true
end
require File.expand_path('../lib/declarative/option/version', __FILE__)
Gem::Specification.new do |gem|
gem.authors = ["Nick Sutterer"]
gem.email = ["apotonick@gmail.com"]
gem.description = %q{Dynamic options.}
gem.summary = %q{Dynamic options to evaluate at runtime.}
gem.homepage = "https://github.com/apotonick/declarative-option"
gem.license = "MIT"
gem.files = `git ls-files`.split($\)
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
gem.name = "declarative-option"
gem.require_paths = ["lib"]
gem.version = Declarative::Option::VERSION
gem.add_development_dependency "rake"
gem.add_development_dependency "minitest"
end
require "declarative/option"
module Declarative
Callable = Module.new
def self.Option(value, options={})
Option.new.(value, options)
end
class Option
def call(value, options={})
return lambda_for_proc(value, options) if value.is_a?(Proc)
return lambda_for_symbol(value, options) if value.is_a?(Symbol)
return lambda_for_callable(value, options) if callable?(value, options)
lambda_for_static(value, options)
end
private
# All methods below are considered public API and are meant to be overridden.
def callable?(value, options)
value.is_a?(options[:callable] || Callable)
end
def lambda_for_proc(value, options)
return ->(context, *args) { context.instance_exec(*args, &value) } if options[:instance_exec]
value
end
def lambda_for_symbol(value, options)
->(context, *args){ context.send(value, *args) }
end
def lambda_for_callable(value, options)
value
end
def lambda_for_static(value, options)
->(*) { value }
end
end
end
module Declarative
class Option
VERSION = "0.1.0"
end
end
require "declarative/option"
module Declarative
def self.Options(options, config={})
Options.new.tap do |hsh|
options.each { |k,v| hsh[k] = Option(v, config) }
end
end
class Options < Hash
# Evaluates every element and returns a hash. Accepts context and arbitrary arguments.
def call(context, *args)
Hash[ collect { |k,v| [k,v.(context, *args) ] } ]
end
end
end
require "test_helper"
require "declarative/option"
class OptionTest < Minitest::Spec
def Option(*args)
Declarative::Option(*args)
end
# proc
it { Option( ->(*args) { "proc! #{args.inspect}" } ).(1,2).must_equal "proc! [1, 2]" }
it { Option( lambda { "proc!" } ).().must_equal "proc!" }
# proc with instance_exec
it { Option( ->(*args) { "#{self.class} #{args.inspect}" } ).(Object, 1, 2).must_equal "OptionTest [Object, 1, 2]" }
it { Option( ->(*args) { "#{self} #{args.inspect}" }, instance_exec: true ).(Object, 1, 2).must_equal "Object [1, 2]" }
# static
it { Option(true).().must_equal true }
it { Option(nil).().must_equal nil }
it { Option(false).().must_equal false }
# args are ignored.
it { Option(true).(1,2,3).must_equal true }
# instance method
class Hello
def hello(*args); "Hello! #{args.inspect}" end
end
it { Option(:hello).(Hello.new).must_equal "Hello! []" }
it { Option(:hello).(Hello.new, 1, 2).must_equal "Hello! [1, 2]" }
#---
# Callable
class Callio
include Declarative::Callable
def call(); "callable!" end
end
it { Option(Callio.new).().must_equal "callable!" }
#---
#- :callable overrides the marking class
class Callme
def call(*args); "callme! #{args}" end
end
it { Option(Callme.new, callable: Callme).().must_equal "callme! []" }
# { callable: Object } will do
# 1. proc?
# 2. method?
# 3. everything else is treated as callable.
describe "callable: Object" do
let (:options) { { callable: Object } }
it { Option(Callme.new, options).(1).must_equal "callme! [1]" }
# proc is detected before callable.
it { Option(->(*args) { "proc! #{args}" }, options).(1).must_equal "proc! [1]" }
# :method is detected before callable.
it { Option(:hello, options).(Hello.new, 1).must_equal "Hello! [1]" }
end
#---
#- override #callable?
class MyCallableOption < Declarative::Option
def callable?(*); true end
end
it { MyCallableOption.new.(Callme.new).().must_equal "callme! []" }
# proc is detected before callable.
it { MyCallableOption.new.(->(*args) { "proc! #{args.inspect}" }).(1).must_equal "proc! [1]" }
# :method is detected before callable.
it { MyCallableOption.new.(:hello).(Hello.new, 1).must_equal "Hello! [1]" }
end
require "test_helper"
require "declarative/options"
class OptionsTest < MiniTest::Spec
let (:dynamic) { Declarative::Options({ :volume =>1, :style => "Punkrock", :track => Proc.new { |i| i.to_s } }, instance_exec: true) }
describe "#call" do
it { dynamic.(Object.new, 999).must_equal({:volume =>1, :style => "Punkrock", :track => "999"}) }
describe "static" do
let (:static) { Declarative::Options(:volume =>1, :style => "Punkrock") }
it { static.(nil).must_equal({:volume =>1, :style => "Punkrock"}) }
end
end
describe "Options() with value options" do
let (:context) { Struct.new(:style).new("Rocksteady") }
it "accepts :instance_exec" do
options = Declarative::Options( { volume: 1, style: lambda { style } }, instance_exec: true )
options.(context).must_equal({:volume=>1, :style=>"Rocksteady"})
end
it "doesn't set :instance_exec per default" do
style = "Metal"
options = Declarative::Options( { volume: 1, style: lambda { |ctx| style } } )
options.(context).must_equal({:volume=>1, :style=>"Metal"})
end
end
end
require "minitest/autorun"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment