Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

init

  • Loading branch information...
commit 15506d40abf2f8138c3e8ddca01c3112b07fef46 0 parents
@kachick authored
35 .gitignore
@@ -0,0 +1,35 @@
+*.gem
+*.rbc
+.bundle
+.config
+coverage
+coverage.data
+InstalledFiles
+lib/bundler/man
+pkg
+rdoc
+spec/reports
+test/tmp
+test/version_tmp
+tmp
+
+# bundler
+vendor/
+
+# YARD artifacts
+.yardoc
+_yardoc
+doc/
+
+# tmp-old
+.old
+
+# editor
+*~
+.redcar
+
+# other
+*.lock
+*.bak
+tool/
+*\#*
14 .travis.yml
@@ -0,0 +1,14 @@
+language: ruby
+rvm:
+ - ruby-head
+ - 1.9.3
+ - 1.9.2
+ - rbx-19mode
+ - jruby-head
+ - jruby-19mode
+
+matrix:
+ allow_failures:
+ - rvm: rbx-19mode
+ - rvm: jruby-head
+ - rvm: jruby-19mode
1  .yardopts
@@ -0,0 +1 @@
+--readme README.md --private lib/**/*.rb - LICENSE
11 Gemfile
@@ -0,0 +1,11 @@
+source 'https://rubygems.org'
+
+gemspec
+
+group :development do
+ gem 'rake'
+end
+
+group :test do
+ gem 'rake'
+end
22 LICENSE
@@ -0,0 +1,22 @@
+(The MIT X11 License)
+
+Copyright (c) 2012 Kenichi Kamiya
+
+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.
55 README.md
@@ -0,0 +1,55 @@
+optionalargument
+=================
+
+Description
+-----------
+
+"like keyword arguments"++
+
+Features
+--------
+
+* Definition so flexible.
+* Can easy use the parsed object.
+* Pure Ruby :)
+
+Usage
+-----
+
+```ruby
+
+```
+
+Requirements
+-------------
+
+* Ruby - [1.9.2 or later](http://travis-ci.org/#!/kachick/optionalargument)
+
+Install
+-------
+
+```bash
+$ gem install optionalargument
+```
+
+Build Status
+-------------
+
+[![Build Status](https://secure.travis-ci.org/kachick/optionalargument.png)](http://travis-ci.org/kachick/optionalargument)
+
+Link
+----
+
+* [code](https://github.com/kachick/optionalargument)
+* [API](http://kachick.github.com/optionalargument/yard/frames.html)
+* [issues](https://github.com/kachick/optionalargument/issues)
+* [CI](http://travis-ci.org/#!/kachick/optionalargument)
+* [gem](https://rubygems.org/gems/optionalargument)
+
+License
+--------
+
+The MIT X11 License
+Copyright (c) 2012 Kenichi Kamiya
+See the file LICENSE for further details.
+
10 Rakefile
@@ -0,0 +1,10 @@
+#!/usr/bin/env rake
+require 'bundler/gem_tasks'
+
+require 'rake/testtask'
+
+task default: [:test]
+
+Rake::TestTask.new do |tt|
+ tt.verbose = true
+end
24 example/README.rb
@@ -0,0 +1,24 @@
+$VERBOSE = true
+
+require_relative '../lib/optionalargument'
+
+class Foo
+
+ FUNC_OPTION = OptionalArgument.define do
+ opt :a, default: ':)', aliases: [:b, :c]
+ opt :f, must: true
+ end
+
+ p FUNC_OPTION.ancestors
+
+ def func(options={})
+ opts = FUNC_OPTION.parse(options)
+ if opts.a?
+ p opts.a
+ end
+ end
+
+end
+
+foo = Foo.new
+foo.func b: 9, f: 7
5 lib/optionalargument.rb
@@ -0,0 +1,5 @@
+# Copyright (c) 2012 Kenichi kamiya
+
+require_relative 'optionalargument/errors'
+require_relative 'optionalargument/store'
+require_relative 'optionalargument/singleton_class'
7 lib/optionalargument/errors.rb
@@ -0,0 +1,7 @@
+module OptionalArgument
+
+ class ParseError < StandardError; end
+ class UndefinedNameError < ParseError; end
+ class KeyConflictError < ParseError; end
+
+end
19 lib/optionalargument/singleton_class.rb
@@ -0,0 +1,19 @@
+module OptionalArgument
+
+ class << self
+
+ # @yieldreturn [Class] subclass of Store
+ # @return [void] must block given
+ def define(&block)
+ raise ArgumentError, 'block was not given' unless block_given?
+
+ Class.new Store do
+ @names = {} # autonym/alias => autonym
+ @must_autonyms = []
+ class_eval(&block)
+ end
+ end
+
+ end
+
+end
118 lib/optionalargument/store.rb
@@ -0,0 +1,118 @@
+require 'keyvalidatable'
+
+module OptionalArgument
+
+ class Store
+
+ class << self
+
+ # @param [Hash] options
+ # @return [Store]
+ def for_options(options)
+ hash = {}
+
+ options.each_pair do |key, value|
+ key = key.to_sym
+ raise UndefinedNameError, key unless @names.has_key? key
+ raise KeyConflictError, key if hash.has_key? key
+ autonym = autonym_for_name key
+ hash[autonym] = value
+ end
+
+ shortage_keys = \
+ @must_autonyms - hash.keys.map{|key|autonym_for_name key}
+
+ unless shortage_keys.empty?
+ raise TypeError,
+ "shortage option parameter: #{shortage_keys.join(', ')}"
+ end
+
+ new hash
+ end
+
+ alias_method :parse, :for_options
+
+ # @param [Symbol, String, #to_sym] name
+ # @return [Symbol] autonym
+ def autonym_for_name(name)
+ @names.fetch name.to_sym
+ end
+
+ private
+
+ DEFAULT_ON_OPTIONS = {
+ must: false,
+ aliases: []
+ }.freeze
+
+ # @param [Symbol, String, #to_sym] autonym
+ # @param [Hash] options
+ # @return [nil]
+ def opt(autonym, options={})
+ autonym = autonym.to_sym
+ options = DEFAULT_ON_OPTIONS.merge(options).extend(KeyValidatable)
+ options.validate_keys must: [:must, :aliases], let: [:default]
+
+ aliases = options[:aliases].map(&:to_sym)
+ names = [autonym, *aliases]
+
+ if options[:must]
+ if options.has_key?(:default)
+ raise ArgumentError, 'conflict "must" with "default"'
+ end
+
+ @must_autonyms << autonym
+ end
+
+ names.each do |name|
+ raise KeyError if @names.has_key? name
+ @names[name] = autonym
+ end
+
+ names.each do |name|
+ define_method name do
+ if options.has_key? :default
+ @hash.has_key?(autonym) ? @hash[autonym] : options[:default]
+ else
+ @hash[autonym]
+ end
+ end
+
+ predicate = "with_#{name}?".to_sym
+ define_method predicate do
+ if options.has_key? :default
+ true
+ else
+ @hash.has_key? autonym
+ end
+ end
+
+ alias_method "#{name}?".to_sym, predicate
+
+ nil
+ end
+ end
+
+ end
+
+ # @param [Hash] hash
+ def initialize(hash)
+ @hash = hash
+ end
+
+ # @param [Symbol, String, #to_sym] name
+ def [](name)
+ @hash.fetch self.class.autonym_for_name(name)
+ end
+
+ # @return [String]
+ def inspect
+ body = @hash.each_pair.map{|k, v|"#{k}=#{v.inspect}"}.join(', ')
+ "#<#{self.class.name}: #{body}>"
+ end
+
+ alias_method :to_s, :inspect
+
+ end
+
+end
23 optionalargument.gemspec
@@ -0,0 +1,23 @@
+Gem::Specification.new do |gem|
+ gem.authors = ['Kenichi Kamiya']
+ gem.email = ['kachick1+ruby@gmail.com']
+ gem.summary = %q{Flexible define and easy parse keyword like arguments.}
+ gem.description = %q{Flexible define and easy parse keyword like arguments.}
+ gem.homepage = 'https://github.com/kachick/optionalargument'
+
+ 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 = 'optionalargument'
+ gem.require_paths = ['lib']
+ gem.version = '0.0.1'
+
+ gem.required_ruby_version = '>= 1.9.2'
+
+ gem.add_runtime_dependency 'keyvalidatable', '~> 0.0.3'
+
+ gem.add_development_dependency 'yard', '~> 0.8'
+ gem.add_development_dependency 'rake'
+ gem.add_development_dependency 'bundler'
+end
+
5 test/helper.rb
@@ -0,0 +1,5 @@
+require 'test/unit'
+
+$VERBOSE = true
+
+require_relative '../lib/optionalargument'
30 test/test_optionalargument.rb
@@ -0,0 +1,30 @@
+require_relative 'helper'
+
+class Test_OptionalArgument < Test::Unit::TestCase
+
+ class Foo
+
+ FUNC_OPTIONS = OptionalArgument.define {
+ opt :full_name, must: true, aliases: [:name, :fullname]
+ opt :favorite, default: 'Ruby'
+ }
+
+ def func(options={})
+ FUNC_OPTIONS.parse options
+ end
+
+ end
+
+ def test_constructor
+ assert_same OptionalArgument::Store, Foo::FUNC_OPTIONS.superclass
+ foo = Foo.new
+ assert_instance_of Foo::FUNC_OPTIONS, foo.func(name: 'John')
+ end
+
+ def test_func
+ assert_same OptionalArgument::Store, Foo::FUNC_OPTIONS.superclass
+ foo = Foo.new
+ assert_instance_of Foo::FUNC_OPTIONS, foo.func(name: 'John')
+ end
+
+end
Please sign in to comment.
Something went wrong with that request. Please try again.