declarative-option 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0205cee16d2b35d8a75aca3798f101c5e27ecb01
4
+ data.tar.gz: bda31c97b0d221e6ce2677acc671cca006839d01
5
+ SHA512:
6
+ metadata.gz: 8469855cdb8a3e0ebe496948cc44defdb208c2bd3bf18accb270effdb4d5a32f09dece7be951299c0005d15f59f479702854fd58a95bbae2458f6b1672f9955d
7
+ data.tar.gz: b6f7b9d9932f48d513cad8a09f9490ac1021c4fb9bdec25872553095166965b9e9d44fd05b0cb1fb2de85d0da442b4d33e7d135a704cc98782f84b0a00dfaee4
@@ -0,0 +1,50 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+
13
+ # Used by dotenv library to load environment variables.
14
+ # .env
15
+
16
+ ## Specific to RubyMotion:
17
+ .dat*
18
+ .repl_history
19
+ build/
20
+ *.bridgesupport
21
+ build-iPhoneOS/
22
+ build-iPhoneSimulator/
23
+
24
+ ## Specific to RubyMotion (use of CocoaPods):
25
+ #
26
+ # We recommend against adding the Pods directory to your .gitignore. However
27
+ # you should judge for yourself, the pros and cons are mentioned at:
28
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
29
+ #
30
+ # vendor/Pods/
31
+
32
+ ## Documentation cache and generated files:
33
+ /.yardoc/
34
+ /_yardoc/
35
+ /doc/
36
+ /rdoc/
37
+
38
+ ## Environment normalization:
39
+ /.bundle/
40
+ /vendor/bundle
41
+ /lib/bundler/man/
42
+
43
+ # for a library or gem, you might want to ignore these files since the code is
44
+ # intended to run in multiple environments; otherwise, check them in:
45
+ # Gemfile.lock
46
+ # .ruby-version
47
+ # .ruby-gemset
48
+
49
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
50
+ .rvmrc
@@ -0,0 +1,11 @@
1
+ rvm:
2
+ - 1.9.3
3
+ - 2.0.0
4
+ - 2.1
5
+ - 2.2
6
+ - 2.3.1
7
+ - 2.4.0
8
+ - jruby-19mode
9
+ - jruby
10
+ before_install:
11
+ - gem install bundler
@@ -0,0 +1,3 @@
1
+ # 0.1.0
2
+
3
+ * Introduce `Declarative::Option` and `Declarative::Options` as a replacement for `Uber::Options::Value` and `Uber::Options`.
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in uber.gemspec
4
+ gemspec
5
+
6
+ gem "benchmark-ips"
7
+ gem "minitest-line"
8
+ gem "rake"
@@ -0,0 +1,26 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ declarative-option (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ benchmark-ips (2.7.2)
10
+ minitest (5.10.1)
11
+ minitest-line (0.6.3)
12
+ minitest (~> 5.0)
13
+ rake (12.0.0)
14
+
15
+ PLATFORMS
16
+ ruby
17
+
18
+ DEPENDENCIES
19
+ benchmark-ips
20
+ declarative-option!
21
+ minitest
22
+ minitest-line
23
+ rake
24
+
25
+ BUNDLED WITH
26
+ 1.12.5
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Nick Sutterer
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,62 @@
1
+ # Declarative::Option
2
+
3
+ _Dynamic options to evaluate at runtime._
4
+
5
+ ## Installation
6
+
7
+ [![Gem Version](https://badge.fury.io/rb/mega-option.svg)](http://badge.fury.io/rb/mega-option)
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'mega-options'
13
+ ```
14
+
15
+ Runs with Ruby >= 1.9.3.
16
+
17
+ # Option
18
+
19
+ 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.
20
+
21
+ It works with static values.
22
+
23
+ ```ruby
24
+ option = Declarative::Option(false)
25
+ option.(context, *args) #=> false
26
+ ```
27
+
28
+ 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`.
29
+
30
+ ```ruby
31
+ option = Declarative::Option(:object_id)
32
+ option.(Object.new, *args) #=> 2354383
33
+ ```
34
+
35
+ Same with objects marked with `Callable`.
36
+
37
+ ```ruby
38
+ class CallMe
39
+ include Declarative::Callable
40
+
41
+ def call(context, *args)
42
+ puts "hello!"
43
+ end
44
+ end
45
+
46
+ option = Declarative::Option(Callable.new) #=> "hello!"
47
+ ```
48
+
49
+ And of course, with lambdas.
50
+
51
+ ```ruby
52
+ option = Declarative::Option( ->(context, *args) { puts "yo!" } )
53
+ option.(context) #=> yo!
54
+ ```
55
+
56
+ All `call` arguments behind the first are passed to the wrapped value.
57
+
58
+ # License
59
+
60
+ Copyright (c) 2017 by Nick Sutterer <apotonick@gmail.com>
61
+
62
+ Uber is released under the [MIT License](http://www.opensource.org/licenses/MIT).
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ require 'rake/testtask'
5
+
6
+ desc 'Test the representable gem.'
7
+ task :default => :test
8
+
9
+ Rake::TestTask.new(:test) do |test|
10
+ test.libs << 'test'
11
+ test.test_files = FileList['test/*_test.rb']
12
+ test.verbose = true
13
+ end
@@ -0,0 +1,20 @@
1
+ require File.expand_path('../lib/declarative/option/version', __FILE__)
2
+
3
+ Gem::Specification.new do |gem|
4
+ gem.authors = ["Nick Sutterer"]
5
+ gem.email = ["apotonick@gmail.com"]
6
+ gem.description = %q{Dynamic options.}
7
+ gem.summary = %q{Dynamic options to evaluate at runtime.}
8
+ gem.homepage = "https://github.com/apotonick/declarative-option"
9
+ gem.license = "MIT"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "declarative-option"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Declarative::Option::VERSION
17
+
18
+ gem.add_development_dependency "rake"
19
+ gem.add_development_dependency "minitest"
20
+ end
@@ -0,0 +1 @@
1
+ require "declarative/option"
@@ -0,0 +1,40 @@
1
+ module Declarative
2
+ Callable = Module.new
3
+
4
+ def self.Option(value, options={})
5
+ Option.new.(value, options)
6
+ end
7
+
8
+ class Option
9
+ def call(value, options={})
10
+ return lambda_for_proc(value, options) if value.is_a?(Proc)
11
+ return lambda_for_symbol(value, options) if value.is_a?(Symbol)
12
+ return lambda_for_callable(value, options) if callable?(value, options)
13
+ lambda_for_static(value, options)
14
+ end
15
+
16
+ private
17
+
18
+ # All methods below are considered public API and are meant to be overridden.
19
+ def callable?(value, options)
20
+ value.is_a?(options[:callable] || Callable)
21
+ end
22
+
23
+ def lambda_for_proc(value, options)
24
+ return ->(context, *args) { context.instance_exec(*args, &value) } if options[:instance_exec]
25
+ value
26
+ end
27
+
28
+ def lambda_for_symbol(value, options)
29
+ ->(context, *args){ context.send(value, *args) }
30
+ end
31
+
32
+ def lambda_for_callable(value, options)
33
+ value
34
+ end
35
+
36
+ def lambda_for_static(value, options)
37
+ ->(*) { value }
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,5 @@
1
+ module Declarative
2
+ class Option
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,16 @@
1
+ require "declarative/option"
2
+
3
+ module Declarative
4
+ def self.Options(options, config={})
5
+ Options.new.tap do |hsh|
6
+ options.each { |k,v| hsh[k] = Option(v, config) }
7
+ end
8
+ end
9
+
10
+ class Options < Hash
11
+ # Evaluates every element and returns a hash. Accepts context and arbitrary arguments.
12
+ def call(context, *args)
13
+ Hash[ collect { |k,v| [k,v.(context, *args) ] } ]
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,72 @@
1
+ require "test_helper"
2
+ require "declarative/option"
3
+
4
+ class OptionTest < Minitest::Spec
5
+ def Option(*args)
6
+ Declarative::Option(*args)
7
+ end
8
+
9
+ # proc
10
+ it { Option( ->(*args) { "proc! #{args.inspect}" } ).(1,2).must_equal "proc! [1, 2]" }
11
+ it { Option( lambda { "proc!" } ).().must_equal "proc!" }
12
+
13
+ # proc with instance_exec
14
+ it { Option( ->(*args) { "#{self.class} #{args.inspect}" } ).(Object, 1, 2).must_equal "OptionTest [Object, 1, 2]" }
15
+ it { Option( ->(*args) { "#{self} #{args.inspect}" }, instance_exec: true ).(Object, 1, 2).must_equal "Object [1, 2]" }
16
+
17
+ # static
18
+ it { Option(true).().must_equal true }
19
+ it { Option(nil).().must_equal nil }
20
+ it { Option(false).().must_equal false }
21
+ # args are ignored.
22
+ it { Option(true).(1,2,3).must_equal true }
23
+
24
+ # instance method
25
+ class Hello
26
+ def hello(*args); "Hello! #{args.inspect}" end
27
+ end
28
+ it { Option(:hello).(Hello.new).must_equal "Hello! []" }
29
+ it { Option(:hello).(Hello.new, 1, 2).must_equal "Hello! [1, 2]" }
30
+
31
+ #---
32
+ # Callable
33
+ class Callio
34
+ include Declarative::Callable
35
+ def call(); "callable!" end
36
+ end
37
+
38
+ it { Option(Callio.new).().must_equal "callable!" }
39
+
40
+ #---
41
+ #- :callable overrides the marking class
42
+ class Callme
43
+ def call(*args); "callme! #{args}" end
44
+ end
45
+ it { Option(Callme.new, callable: Callme).().must_equal "callme! []" }
46
+
47
+ # { callable: Object } will do
48
+ # 1. proc?
49
+ # 2. method?
50
+ # 3. everything else is treated as callable.
51
+ describe "callable: Object" do
52
+ let (:options) { { callable: Object } }
53
+
54
+ it { Option(Callme.new, options).(1).must_equal "callme! [1]" }
55
+ # proc is detected before callable.
56
+ it { Option(->(*args) { "proc! #{args}" }, options).(1).must_equal "proc! [1]" }
57
+ # :method is detected before callable.
58
+ it { Option(:hello, options).(Hello.new, 1).must_equal "Hello! [1]" }
59
+ end
60
+
61
+ #---
62
+ #- override #callable?
63
+ class MyCallableOption < Declarative::Option
64
+ def callable?(*); true end
65
+ end
66
+
67
+ it { MyCallableOption.new.(Callme.new).().must_equal "callme! []" }
68
+ # proc is detected before callable.
69
+ it { MyCallableOption.new.(->(*args) { "proc! #{args.inspect}" }).(1).must_equal "proc! [1]" }
70
+ # :method is detected before callable.
71
+ it { MyCallableOption.new.(:hello).(Hello.new, 1).must_equal "Hello! [1]" }
72
+ end
@@ -0,0 +1,32 @@
1
+ require "test_helper"
2
+ require "declarative/options"
3
+
4
+ class OptionsTest < MiniTest::Spec
5
+ let (:dynamic) { Declarative::Options({ :volume =>1, :style => "Punkrock", :track => Proc.new { |i| i.to_s } }, instance_exec: true) }
6
+
7
+ describe "#call" do
8
+ it { dynamic.(Object.new, 999).must_equal({:volume =>1, :style => "Punkrock", :track => "999"}) }
9
+
10
+ describe "static" do
11
+ let (:static) { Declarative::Options(:volume =>1, :style => "Punkrock") }
12
+
13
+ it { static.(nil).must_equal({:volume =>1, :style => "Punkrock"}) }
14
+ end
15
+ end
16
+
17
+ describe "Options() with value options" do
18
+ let (:context) { Struct.new(:style).new("Rocksteady") }
19
+
20
+ it "accepts :instance_exec" do
21
+ options = Declarative::Options( { volume: 1, style: lambda { style } }, instance_exec: true )
22
+
23
+ options.(context).must_equal({:volume=>1, :style=>"Rocksteady"})
24
+ end
25
+
26
+ it "doesn't set :instance_exec per default" do
27
+ style = "Metal"
28
+ options = Declarative::Options( { volume: 1, style: lambda { |ctx| style } } )
29
+ options.(context).must_equal({:volume=>1, :style=>"Metal"})
30
+ end
31
+ end
32
+ end
@@ -0,0 +1 @@
1
+ require "minitest/autorun"
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: declarative-option
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Nick Sutterer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-01-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Dynamic options.
42
+ email:
43
+ - apotonick@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".gitignore"
49
+ - ".travis.yml"
50
+ - CHANGES.md
51
+ - Gemfile
52
+ - Gemfile.lock
53
+ - LICENSE
54
+ - README.md
55
+ - Rakefile
56
+ - declarative-option.gemspec
57
+ - lib/declarative-option.rb
58
+ - lib/declarative/option.rb
59
+ - lib/declarative/option/version.rb
60
+ - lib/declarative/options.rb
61
+ - test/option_test.rb
62
+ - test/options_test.rb
63
+ - test/test_helper.rb
64
+ homepage: https://github.com/apotonick/declarative-option
65
+ licenses:
66
+ - MIT
67
+ metadata: {}
68
+ post_install_message:
69
+ rdoc_options: []
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ requirements: []
83
+ rubyforge_project:
84
+ rubygems_version: 2.6.3
85
+ signing_key:
86
+ specification_version: 4
87
+ summary: Dynamic options to evaluate at runtime.
88
+ test_files:
89
+ - test/option_test.rb
90
+ - test/options_test.rb
91
+ - test/test_helper.rb