declarative-option-0.1.0/0000755000175000017500000000000013137577520014337 5ustar pravipravideclarative-option-0.1.0/Gemfile.lock0000644000175000017500000000053313137577520016562 0ustar pravipraviPATH 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 declarative-option-0.1.0/README.md0000644000175000017500000000250713137577520015622 0ustar pravipravi# 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 Uber is released under the [MIT License](http://www.opensource.org/licenses/MIT). declarative-option-0.1.0/declarative-option.gemspec0000644000175000017500000000144213137577520021476 0ustar pravipravirequire 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 declarative-option-0.1.0/lib/0000755000175000017500000000000013137577520015105 5ustar pravipravideclarative-option-0.1.0/lib/declarative/0000755000175000017500000000000013137577520017370 5ustar pravipravideclarative-option-0.1.0/lib/declarative/options.rb0000644000175000017500000000064013137577520021410 0ustar pravipravirequire "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 declarative-option-0.1.0/lib/declarative/option.rb0000644000175000017500000000201413137577520021222 0ustar pravipravimodule 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 declarative-option-0.1.0/lib/declarative/option/0000755000175000017500000000000013137577520020700 5ustar pravipravideclarative-option-0.1.0/lib/declarative/option/version.rb0000644000175000017500000000010213137577520022703 0ustar pravipravimodule Declarative class Option VERSION = "0.1.0" end end declarative-option-0.1.0/lib/declarative-option.rb0000644000175000017500000000003513137577520021221 0ustar pravipravirequire "declarative/option" declarative-option-0.1.0/.travis.yml0000644000175000017500000000020013137577520016440 0ustar pravipravirvm: - 1.9.3 - 2.0.0 - 2.1 - 2.2 - 2.3.1 - 2.4.0 - jruby-19mode - jruby before_install: - gem install bundler declarative-option-0.1.0/.gitignore0000644000175000017500000000203213137577520016324 0ustar pravipravi*.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 declarative-option-0.1.0/LICENSE0000644000175000017500000000205513137577520015346 0ustar pravipraviCopyright (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.declarative-option-0.1.0/Rakefile0000644000175000017500000000041013137577520015777 0ustar pravipravi#!/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 declarative-option-0.1.0/Gemfile0000644000175000017500000000021513137577520015630 0ustar pravipravisource 'https://rubygems.org' # Specify your gem's dependencies in uber.gemspec gemspec gem "benchmark-ips" gem "minitest-line" gem "rake" declarative-option-0.1.0/test/0000755000175000017500000000000013137577520015316 5ustar pravipravideclarative-option-0.1.0/test/option_test.rb0000644000175000017500000000444113137577520020215 0ustar pravipravirequire "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 declarative-option-0.1.0/test/test_helper.rb0000644000175000017500000000003313137577520020155 0ustar pravipravirequire "minitest/autorun" declarative-option-0.1.0/test/options_test.rb0000644000175000017500000000212613137577520020376 0ustar pravipravirequire "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 declarative-option-0.1.0/CHANGES.md0000644000175000017500000000020713137577520015730 0ustar pravipravi# 0.1.0 * Introduce `Declarative::Option` and `Declarative::Options` as a replacement for `Uber::Options::Value` and `Uber::Options`.