options 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
@@ -0,0 +1,151 @@
1
+ NAME
2
+ options.rb
3
+
4
+ DESCRIPTION
5
+ options.rb simplifies the common idiom of dealing with keyword options in
6
+ ruby functions. it also deals correctly with symbol vs string keywords and
7
+ prevents many subtle programming errors that can arise from doing so
8
+ incorrectly. options.rb doesn't hack ruby's core with one exception: the
9
+ method Array#options.
10
+
11
+ SYNOPSIS
12
+ require 'options'
13
+
14
+ def method(*args, &block)
15
+ args, options = Options.parse(args)
16
+
17
+ a = args.shift
18
+ b = args.shift
19
+
20
+ force = options.getopt(:force, default = false)
21
+ verbose = options.getopt([:verbose, :VERBOSE])
22
+ foo, bar = options.getopt(:foo, :bar)
23
+ end
24
+
25
+ INSTALL
26
+ gem install options
27
+
28
+ SAMPLES
29
+
30
+ <========< samples/a.rb >========>
31
+
32
+ ~ > cat samples/a.rb
33
+
34
+ require 'options'
35
+
36
+ # options.rb makes is super easy to deal with keyword options in a safe and
37
+ # easy way.
38
+ #
39
+
40
+ def method(*args)
41
+ args, options = Options.parse(args)
42
+
43
+ force = options.getopt(:force, default=false)
44
+ p force
45
+ end
46
+
47
+ method(:foo, :bar, :force => true)
48
+ method('force' => true)
49
+
50
+ ~ > ruby samples/a.rb
51
+
52
+ true
53
+ true
54
+
55
+
56
+ <========< samples/b.rb >========>
57
+
58
+ ~ > cat samples/b.rb
59
+
60
+ require 'options'
61
+
62
+ # options.rb avoids common mistakes made handling keyword arguments
63
+ #
64
+
65
+ def broken(*args)
66
+ options = args.last.is_a?(Hash) ? args.pop : {}
67
+ if options[:force]
68
+ puts 'forcing'
69
+ else
70
+ puts 'broken'
71
+ end
72
+ end
73
+
74
+ def nonbroken(*args)
75
+ args, options = Options.parse(args)
76
+ if options.getopt(:force)
77
+ puts 'nonbroken'
78
+ end
79
+ end
80
+
81
+ broken('force' => true)
82
+ nonbroken('force' => true)
83
+
84
+
85
+
86
+ def fubar(*args)
87
+ options = args.last.is_a?(Hash) ? args.pop : {}
88
+ verbose = options[:verbose] || true
89
+ if verbose
90
+ if options[:verbose]
91
+ puts 'verbosely'
92
+ else
93
+ puts 'fubar'
94
+ end
95
+ end
96
+ end
97
+
98
+ def nonfubar(*args)
99
+ args, options = Options.parse(args)
100
+ verbose = options.getopt(:verbose)
101
+ if verbose
102
+ puts 'verbosely'
103
+ else
104
+ puts 'nonfubar'
105
+ end
106
+ end
107
+
108
+ fubar(:verbose => false)
109
+ nonfubar(:verbose => false)
110
+
111
+ ~ > ruby samples/b.rb
112
+
113
+ broken
114
+ nonbroken
115
+ fubar
116
+ nonfubar
117
+
118
+
119
+ <========< samples/c.rb >========>
120
+
121
+ ~ > cat samples/c.rb
122
+
123
+ require 'options'
124
+
125
+ # options.rb hacks ruby core in exactly one way - the method Array#options
126
+ #
127
+
128
+ def method(*args)
129
+ options = args.options
130
+ p :args => args
131
+ p :options => options
132
+ end
133
+
134
+ method(:a, :b, :k => :v)
135
+
136
+ def method2(*args)
137
+ options = args.options.pop
138
+ p :args => args
139
+ p :options => options
140
+ end
141
+
142
+ method2(:a, :b, :k => :v)
143
+
144
+ ~ > ruby samples/c.rb
145
+
146
+ {:args=>[:a, :b, {:k=>:v}]}
147
+ {:options=>{:k=>:v}}
148
+ {:args=>[:a, :b]}
149
+ {:options=>{:k=>:v}}
150
+
151
+
data/README.rb ADDED
@@ -0,0 +1,80 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ template = <<-__
4
+ NAME
5
+ options.rb
6
+
7
+ DESCRIPTION
8
+ options.rb simplifies the common idiom of dealing with keyword options in
9
+ ruby functions. it also deals correctly with symbol vs string keywords and
10
+ prevents many subtle programming errors that can arise from doing so
11
+ incorrectly. options.rb doesn't hack ruby's core with one exception: the
12
+ method Array#options.
13
+
14
+ SYNOPSIS
15
+ require 'options'
16
+
17
+ def method(*args, &block)
18
+ args, options = Options.parse(args)
19
+
20
+ a = args.shift
21
+ b = args.shift
22
+
23
+ force = options.getopt(:force, default = false)
24
+ verbose = options.getopt([:verbose, :VERBOSE])
25
+ foo, bar = options.getopt(:foo, :bar)
26
+ end
27
+
28
+ INSTALL
29
+ gem install options
30
+
31
+ SAMPLES
32
+ <%= samples %>
33
+ __
34
+
35
+
36
+ require 'erb'
37
+ require 'pathname'
38
+
39
+ $VERBOSE=nil
40
+
41
+ def indent(s, n = 2)
42
+ s = unindent(s)
43
+ ws = ' ' * n
44
+ s.gsub(%r/^/, ws)
45
+ end
46
+
47
+ def unindent(s)
48
+ indent = nil
49
+ s.each do |line|
50
+ next if line =~ %r/^\s*$/
51
+ indent = line[%r/^\s*/] and break
52
+ end
53
+ indent ? s.gsub(%r/^#{ indent }/, "") : s
54
+ end
55
+
56
+ samples = ''
57
+ prompt = '~ > '
58
+
59
+ Dir.chdir(File.dirname(__FILE__))
60
+
61
+ Dir['sample*/*'].sort.each do |sample|
62
+ samples << "\n" << " <========< #{ sample } >========>" << "\n\n"
63
+
64
+ cmd = "cat #{ sample }"
65
+ samples << indent(prompt + cmd, 2) << "\n\n"
66
+ samples << indent(`#{ cmd }`, 4) << "\n"
67
+
68
+ cmd = "ruby #{ sample }"
69
+ samples << indent(prompt + cmd, 2) << "\n\n"
70
+
71
+ cmd = "ruby -e'STDOUT.sync=true; exec %(ruby -Ilib #{ sample })'"
72
+ #cmd = "ruby -Ilib #{ sample }"
73
+ samples << indent(`#{ cmd } 2>&1`, 4) << "\n"
74
+ end
75
+
76
+ erb = ERB.new(unindent(template))
77
+ result = erb.result(binding)
78
+ #open('README', 'w'){|fd| fd.write result}
79
+ #puts unindent(result)
80
+ puts result
data/gemspec.rb ADDED
@@ -0,0 +1,62 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ lib, version, *ignored = ARGV
4
+
5
+ unless lib
6
+ lib = File.basename(Dir.pwd)
7
+ end
8
+
9
+ unless version
10
+ mod = lib.capitalize
11
+ require "./lib/#{ lib }"
12
+ version = eval(mod).send(:version)
13
+ end
14
+
15
+ abort('no lib') unless lib
16
+ abort('no version') unless version
17
+
18
+ puts "### gemspec: #{ lib }-#{ version }"
19
+
20
+ $VERBOSE = nil
21
+
22
+ shiteless = lambda{|list| list.delete_if{|file| file =~ %r/\.(git|svn|tmp|sw.|bak)$/}}
23
+
24
+ files = shiteless[Dir::glob("**/**")]
25
+ executables = shiteless[Dir::glob("bin/*")].map{|exe| File.basename(exe)}
26
+ has_rdoc = true #File.exist?('doc')
27
+ test_files = "test/#{ lib }.rb" if File.file?("test/#{ lib }.rb")
28
+
29
+ extensions = []
30
+ %w( Makefile configure extconf.rb rakefile Rakefile mkrf_conf ).each do |ext|
31
+ extensions << ext if File.exists?(ext)
32
+ end
33
+
34
+ template = <<-__
35
+
36
+ Gem::Specification::new do |spec|
37
+ spec.name = #{ lib.inspect }
38
+ spec.version = #{ version.inspect }
39
+ spec.platform = Gem::Platform::RUBY
40
+ spec.summary = #{ lib.inspect }
41
+
42
+ spec.files = #{ files.inspect }
43
+ spec.executables = #{ executables.inspect }
44
+
45
+ spec.require_path = "lib"
46
+
47
+ spec.has_rdoc = #{ has_rdoc.inspect }
48
+ spec.test_files = #{ test_files.inspect }
49
+ #spec.add_dependency 'lib', '>= version'
50
+ #spec.add_dependency 'fattr'
51
+
52
+ spec.extensions.push(*#{ extensions.inspect })
53
+
54
+ spec.rubyforge_project = 'codeforpeople'
55
+ spec.author = "Ara T. Howard"
56
+ spec.email = "ara.t.howard@gmail.com"
57
+ spec.homepage = "http://github.com/ahoward/#{ lib }/tree/master"
58
+ end
59
+
60
+ __
61
+
62
+ puts template
data/lib/options.rb ADDED
@@ -0,0 +1,192 @@
1
+ module Options
2
+ VERSION = '1.0.0'
3
+
4
+ class << Options
5
+ def version
6
+ Options::VERSION
7
+ end
8
+
9
+ def normalize!(hash)
10
+ hash.keys.each{|key| hash[key.to_s.to_sym] = hash.delete(key) unless Symbol===key}
11
+ hash
12
+ end
13
+ alias_method 'to_options!', 'normalize!'
14
+
15
+ def normalize(hash)
16
+ normalize!(hash.dup)
17
+ end
18
+ alias_method 'to_options', 'normalize'
19
+
20
+ def stringify!(hash)
21
+ hash.keys.each{|key| hash[key.to_s] = hash.delete(key) unless String===key}
22
+ hash
23
+ end
24
+ alias_method 'stringified!', 'stringify!'
25
+
26
+ def stringify(hash)
27
+ stringify!(hash)
28
+ end
29
+ alias_method 'stringified', 'stringify'
30
+
31
+ def for(hash)
32
+ hash =
33
+ case hash
34
+ when Hash
35
+ hash
36
+ when Array
37
+ Hash[*hash.flatten]
38
+ when String, Symbol
39
+ {hash => true}
40
+ else
41
+ hash.to_hash
42
+ end
43
+ normalize!(hash)
44
+ ensure
45
+ hash.extend(Options) unless hash.is_a?(Options)
46
+ end
47
+
48
+ def parse(args)
49
+ args.extend(Arguments) unless args.is_a?(Arguments)
50
+ [args, args.options.pop]
51
+ end
52
+ end
53
+
54
+ def to_options!
55
+ replace to_options
56
+ end
57
+
58
+ def to_options
59
+ keys.inject(Hash.new){|h,k| h.update k.to_s.to_sym => fetch(k)}
60
+ end
61
+
62
+ def getopt key, default = nil
63
+ [ key ].flatten.each do |key|
64
+ return fetch(key) if has_key?(key)
65
+ key = key.to_s
66
+ return fetch(key) if has_key?(key)
67
+ key = key.to_sym
68
+ return fetch(key) if has_key?(key)
69
+ end
70
+ default
71
+ end
72
+
73
+ def getopts *args
74
+ args.flatten.map{|arg| getopt arg}
75
+ end
76
+
77
+ def hasopt key, default = nil
78
+ [ key ].flatten.each do |key|
79
+ return true if has_key?(key)
80
+ key = key.to_s
81
+ return true if has_key?(key)
82
+ key = key.to_sym
83
+ return true if has_key?(key)
84
+ end
85
+ default
86
+ end
87
+ alias_method 'hasopt?', 'hasopt'
88
+
89
+ def hasopts *args
90
+ args.flatten.map{|arg| hasopt arg}
91
+ end
92
+ alias_method 'hasopts?', 'hasopts'
93
+
94
+ def delopt key, default = nil
95
+ [ key ].flatten.each do |key|
96
+ return delete(key) if has_key?(key)
97
+ key = key.to_s
98
+ return delete(key) if has_key?(key)
99
+ key = key.to_sym
100
+ return delete(key) if has_key?(key)
101
+ end
102
+ default
103
+ end
104
+
105
+ def delopts *args
106
+ args.flatten.map{|arg| delopt arg}
107
+ end
108
+
109
+ def setopt key, value = nil
110
+ [ key ].flatten.each do |key|
111
+ return self[key]=value if has_key?(key)
112
+ key = key.to_s
113
+ return self[key]=value if has_key?(key)
114
+ key = key.to_sym
115
+ return self[key]=value if has_key?(key)
116
+ end
117
+ return self[key]=value
118
+ end
119
+ alias_method 'setopt!', 'setopt'
120
+
121
+ def setopts opts
122
+ opts.each{|key, value| setopt key, value}
123
+ opts
124
+ end
125
+ alias_method 'setopts!', 'setopts'
126
+
127
+ def select! *a, &b
128
+ replace select(*a, &b).to_hash
129
+ end
130
+
131
+ def normalize!
132
+ Options.normalize!(self)
133
+ end
134
+ alias_method 'normalized!', 'normalized!'
135
+ alias_method 'to_options!', 'normalize!'
136
+
137
+ def normalize
138
+ Options.normalize(self)
139
+ end
140
+ alias_method 'normalized', 'normalized'
141
+ alias_method 'to_options', 'normalize'
142
+
143
+ def stringify!
144
+ Options.stringify!(self)
145
+ end
146
+ alias_method 'stringified!', 'stringify!'
147
+
148
+ def stringify
149
+ Options.stringify(self)
150
+ end
151
+ alias_method 'stringified', 'stringify'
152
+
153
+ attr_accessor :arguments
154
+ def pop
155
+ pop! unless popped?
156
+ self
157
+ end
158
+
159
+ def popped?
160
+ defined?(@popped) and @popped
161
+ end
162
+
163
+ def pop!
164
+ @popped = arguments.pop
165
+ end
166
+ end
167
+
168
+ module Arguments
169
+ def options
170
+ @options ||= Options.for(last.is_a?(Hash) ? last : {})
171
+ ensure
172
+ @options.arguments = self
173
+ end
174
+
175
+ class << Arguments
176
+ def for(args)
177
+ args.extend(Arguments) unless args.is_a?(Arguments)
178
+ args
179
+ end
180
+
181
+ def parse(args)
182
+ Options.parse(args)
183
+ end
184
+ end
185
+ end
186
+
187
+ class Array
188
+ def options
189
+ extend(Arguments) unless is_a?(Arguments)
190
+ options
191
+ end
192
+ end
data/options.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ ### gemspec: options-1.0.0
2
+
3
+ Gem::Specification::new do |spec|
4
+ spec.name = "options"
5
+ spec.version = "1.0.0"
6
+ spec.platform = Gem::Platform::RUBY
7
+ spec.summary = "options"
8
+
9
+ spec.files = ["gemspec.rb", "lib", "lib/options.rb", "options.gemspec", "README", "README.rb", "samples", "samples/a.rb", "samples/b.rb", "samples/c.rb"]
10
+ spec.executables = []
11
+
12
+ spec.require_path = "lib"
13
+
14
+ spec.has_rdoc = true
15
+ spec.test_files = nil
16
+ #spec.add_dependency 'lib', '>= version'
17
+ #spec.add_dependency 'fattr'
18
+
19
+ spec.extensions.push(*[])
20
+
21
+ spec.rubyforge_project = 'codeforpeople'
22
+ spec.author = "Ara T. Howard"
23
+ spec.email = "ara.t.howard@gmail.com"
24
+ spec.homepage = "http://github.com/ahoward/options/tree/master"
25
+ end
26
+
data/samples/a.rb ADDED
@@ -0,0 +1,15 @@
1
+ require 'options'
2
+
3
+ # options.rb makes is super easy to deal with keyword options in a safe and
4
+ # easy way.
5
+ #
6
+
7
+ def method(*args)
8
+ args, options = Options.parse(args)
9
+
10
+ force = options.getopt(:force, default=false)
11
+ p force
12
+ end
13
+
14
+ method(:foo, :bar, :force => true)
15
+ method('force' => true)
data/samples/b.rb ADDED
@@ -0,0 +1,50 @@
1
+ require 'options'
2
+
3
+ # options.rb avoids common mistakes made handling keyword arguments
4
+ #
5
+
6
+ def broken(*args)
7
+ options = args.last.is_a?(Hash) ? args.pop : {}
8
+ if options[:force]
9
+ puts 'forcing'
10
+ else
11
+ puts 'broken'
12
+ end
13
+ end
14
+
15
+ def nonbroken(*args)
16
+ args, options = Options.parse(args)
17
+ if options.getopt(:force)
18
+ puts 'nonbroken'
19
+ end
20
+ end
21
+
22
+ broken('force' => true)
23
+ nonbroken('force' => true)
24
+
25
+
26
+
27
+ def fubar(*args)
28
+ options = args.last.is_a?(Hash) ? args.pop : {}
29
+ verbose = options[:verbose] || true
30
+ if verbose
31
+ if options[:verbose]
32
+ puts 'verbosely'
33
+ else
34
+ puts 'fubar'
35
+ end
36
+ end
37
+ end
38
+
39
+ def nonfubar(*args)
40
+ args, options = Options.parse(args)
41
+ verbose = options.getopt(:verbose)
42
+ if verbose
43
+ puts 'verbosely'
44
+ else
45
+ puts 'nonfubar'
46
+ end
47
+ end
48
+
49
+ fubar(:verbose => false)
50
+ nonfubar(:verbose => false)
data/samples/c.rb ADDED
@@ -0,0 +1,20 @@
1
+ require 'options'
2
+
3
+ # options.rb hacks ruby core in exactly one way - the method Array#options
4
+ #
5
+
6
+ def method(*args)
7
+ options = args.options
8
+ p :args => args
9
+ p :options => options
10
+ end
11
+
12
+ method(:a, :b, :k => :v)
13
+
14
+ def method2(*args)
15
+ options = args.options.pop
16
+ p :args => args
17
+ p :options => options
18
+ end
19
+
20
+ method2(:a, :b, :k => :v)
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: options
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Ara T. Howard
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-05-31 00:00:00 -06:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: ara.t.howard@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - gemspec.rb
26
+ - lib
27
+ - lib/options.rb
28
+ - options.gemspec
29
+ - README
30
+ - README.rb
31
+ - samples
32
+ - samples/a.rb
33
+ - samples/b.rb
34
+ - samples/c.rb
35
+ has_rdoc: true
36
+ homepage: http://github.com/ahoward/options/tree/master
37
+ post_install_message:
38
+ rdoc_options: []
39
+
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
47
+ version:
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: "0"
53
+ version:
54
+ requirements: []
55
+
56
+ rubyforge_project: codeforpeople
57
+ rubygems_version: 1.3.1
58
+ signing_key:
59
+ specification_version: 2
60
+ summary: options
61
+ test_files: []
62
+