A
Ara.T.Howard
URLS
http://raa.ruby-lang.org/search.rhtml?search=parseargs
http://codeforpeople.com/lib/ruby/parseargs
ABOUT
parseargs is a library that faciltates the parsing of arguments and keywords
from method paramters, setting of default values, validation, contraints via
class based or duck based typing, and coercion/convincing to type/ducktype
when possible.
HISTORY
0.0.0
initial version
AUTHOR
ara [dot] t [dot] howard [at] noaa [dot] gov
SAMPLES
<========< sample/a.rb >========>
~ > ruby -e'puts(IO::read(ARGV.shift))' sample/a.rb
require 'parseargs'
include ParseArgs
#
# simple use will declare which required and optional arguments a method can
# accept. default values may be specifed if a hash is given as the argument
# specification. an exception is thrown if required arguments are not given at
# method invocation.
#
def method(*a)
pa =
parseargs(a) {
required_argument :a
optional_argument :b => 2
}
puts "#{ pa.a }#{ pa.b }"
end
method 4
~ > ruby sample/a.rb
42
<========< sample/b.rb >========>
~ > ruby -e'puts(IO::read(ARGV.shift))' sample/b.rb
require 'parseargs'
include ParseArgs
#
# keywords can be declared in exactly the same way, and can be given at
# invocation as either strings or symbols. default values may also be named for
# both arguments and keywords. note that a required keyword with a default
# specified is really an optional keyword ;-)
#
def method(*a)
pa =
parseargs(a) {
required_argument :a
required_keyword :b, :default => 2
optional_keyword :c
}
puts "#{ pa.a }#{ pa.b }"
end
method 4, 'b' => 2
~ > ruby sample/b.rb
42
<========< sample/c.rb >========>
~ > ruby -e'puts(IO::read(ARGV.shift))' sample/c.rb
require 'parseargs'
include ParseArgs
#
# several abbreviations exist to make the declaration more compact.
#
def method(*a)
pa =
parseargs(a) {
r_arg :a
r_kw :b
o_kw :c
}
if pa.c
puts "#{ pa.c }"
else
puts "#{ pa.a }#{ pa.b }"
end
end
method 4, :b => 2
method 4, :b => 2, 'c' => 42
~ > ruby sample/c.rb
42
42
<========< sample/d.rb >========>
~ > ruby -e'puts(IO::read(ARGV.shift))' sample/d.rb
require 'parseargs'
include ParseArgs
#
# many keywords or arguments can be specified at once using a list
#
def method(*a)
pa =
parseargs(a) {
r_arg 'req_arg'
o_kw ('a'..'z').to_a
}
kw = pa.a ? pa.a : pa.z
puts "#{ pa.req_arg }#{ kw }"
end
method 4, 'a' => 2
method 4, 'z' => 2
~ > ruby sample/d.rb
42
42
<========< sample/e.rb >========>
~ > ruby -e'puts(IO::read(ARGV.shift))' sample/e.rb
require 'parseargs'
include ParseArgs
#
# a single, or list of types may be given and the argument of invocation must be
# one of those types as reports by '==='
#
def method(*a)
pa =
parseargs(a) {
req_arg 'number', 'types' => [Float, Fixnum]
}
p pa.number
end
method 42
method 42.0
method '42.0'
~ > ruby sample/e.rb
42
42.0
./lib/parseargs.rb:112:in `value=': value given not of type(Float,Fixnum) in 'number=' (TypeError)
from ./lib/parseargs.rb:296:in `parse'
from ./lib/parseargs.rb:291:in `each'
from ./lib/parseargs.rb:291:in `parse'
from ./lib/parseargs.rb:393:in `parseargs'
from ./lib/parseargs.rb:376:in `parseargs'
from sample/e.rb:11:in `method'
from sample/e.rb:20
<========< sample/f.rb >========>
~ > ruby -e'puts(IO::read(ARGV.shift))' sample/f.rb
require 'parseargs'
include ParseArgs
#
# failure of an argument to match a given type will cause coercion to be applied
# if specified. the coerce argument may be either a method name or a proc that
# receives the obj to be coerced. in either case the return value is used as
# the new argument.
#
def method(*a)
pa =
parseargs(a) {
arg :a, :types => Fixnum, :coerce => 'to_i'
kw :b, :types => Fixnum, :coerce => lambda{|obj| obj.to_i}
}
p [pa.a, pa.b]
end
method 4, :b => 2
method '4', :b => '2'
~ > ruby sample/f.rb
[4, 2]
[4, 2]
<========< sample/g.rb >========>
~ > ruby -e'puts(IO::read(ARGV.shift))' sample/g.rb
require 'parseargs'
include ParseArgs
#
# ducktyping is supported as a method name, or list of method names - all of
# which an argument must respond_to? in order for an exception not to be thrown.
# this is a very simple ducktype signature.
#
def method(*a)
pa =
parseargs(a) {
r_arg 'string', 'ducktype' => [:upcase, :downcase]
}
puts pa.string.upcase.downcase
end
method ['42']
~ > ruby sample/g.rb
42
<========< sample/h.rb >========>
~ > ruby -e'puts(IO::read(ARGV.shift))' sample/h.rb
require 'parseargs'
include ParseArgs
#
# a kind of ducktype 'coercion' - somthing i'm calling 'convincing' - may be
# applied in order to convince an object that it really can play a certain role.
# an argument may be 'convinced' via a module, which will be used to extend the
# object on the fly, or a block which is passed the object and expected to
# modify it's singleton class in such a way as to allow the object to become a
# valid argument
#
module M
def quack
2
end
end
def method(*a)
pa =
parseargs(a) {
ra 'a', 'ducktype' => :quack,
'convince' => lambda{|obj| class << obj; def quack; 4; end; end}
ra 'b', 'ducktype' => :quack,
'convince' => M
}
puts "#{ pa.a.quack }#{ pa.b.quack }"
end
method 'any ol', 'objects'
~ > ruby sample/h.rb
42
<========< sample/i.rb >========>
~ > ruby -e'puts(IO::read(ARGV.shift))' sample/i.rb
require 'parseargs'
#
# of course all this would be kind of silly for the simple cases shown - but it
# can become very powerful as a form of meta-programming aid or when many
# kewords are to be supported
#
class Command
include ParseArgs
KEYWORDS = %w(
verbose
quiet
log
help
info
force
recursive
stdin
stdout
stderr
)
PARSER =
ParseArgs:arser::new {
KEYWORDS.each{|kw| optional_keyword kw}
}
def initialize cmd
@cmd = cmd
end
def execute(*argv)
opts = PARSER.parse argv
p @cmd => opts.select{|k,v| not v.nil?}
end
def background(*argv)
opts = PARSER.parse argv
p @cmd => opts.select{|k,v| not v.nil?}
end
end
foo = Command::new 'foo.exe'
foo.execute 'verbose' => true, 'stdin' => 'input.txt'
bar = Command::new 'bar.exe'
bar.execute 'verbose' => false, 'stdout' => 'output.txt'
~ > ruby sample/i.rb
{"foo.exe"=>[["stdin", "input.txt"], ["verbose", true]]}
{"bar.exe"=>[["stdout", "output.txt"], ["verbose", false]]}
CAVEATS
this library is experimental.
enjoy.
-a
--
===============================================================================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| My religion is very simple. My religion is kindness.
| --Tenzin Gyatso
===============================================================================
http://raa.ruby-lang.org/search.rhtml?search=parseargs
http://codeforpeople.com/lib/ruby/parseargs
ABOUT
parseargs is a library that faciltates the parsing of arguments and keywords
from method paramters, setting of default values, validation, contraints via
class based or duck based typing, and coercion/convincing to type/ducktype
when possible.
HISTORY
0.0.0
initial version
AUTHOR
ara [dot] t [dot] howard [at] noaa [dot] gov
SAMPLES
<========< sample/a.rb >========>
~ > ruby -e'puts(IO::read(ARGV.shift))' sample/a.rb
require 'parseargs'
include ParseArgs
#
# simple use will declare which required and optional arguments a method can
# accept. default values may be specifed if a hash is given as the argument
# specification. an exception is thrown if required arguments are not given at
# method invocation.
#
def method(*a)
pa =
parseargs(a) {
required_argument :a
optional_argument :b => 2
}
puts "#{ pa.a }#{ pa.b }"
end
method 4
~ > ruby sample/a.rb
42
<========< sample/b.rb >========>
~ > ruby -e'puts(IO::read(ARGV.shift))' sample/b.rb
require 'parseargs'
include ParseArgs
#
# keywords can be declared in exactly the same way, and can be given at
# invocation as either strings or symbols. default values may also be named for
# both arguments and keywords. note that a required keyword with a default
# specified is really an optional keyword ;-)
#
def method(*a)
pa =
parseargs(a) {
required_argument :a
required_keyword :b, :default => 2
optional_keyword :c
}
puts "#{ pa.a }#{ pa.b }"
end
method 4, 'b' => 2
~ > ruby sample/b.rb
42
<========< sample/c.rb >========>
~ > ruby -e'puts(IO::read(ARGV.shift))' sample/c.rb
require 'parseargs'
include ParseArgs
#
# several abbreviations exist to make the declaration more compact.
#
def method(*a)
pa =
parseargs(a) {
r_arg :a
r_kw :b
o_kw :c
}
if pa.c
puts "#{ pa.c }"
else
puts "#{ pa.a }#{ pa.b }"
end
end
method 4, :b => 2
method 4, :b => 2, 'c' => 42
~ > ruby sample/c.rb
42
42
<========< sample/d.rb >========>
~ > ruby -e'puts(IO::read(ARGV.shift))' sample/d.rb
require 'parseargs'
include ParseArgs
#
# many keywords or arguments can be specified at once using a list
#
def method(*a)
pa =
parseargs(a) {
r_arg 'req_arg'
o_kw ('a'..'z').to_a
}
kw = pa.a ? pa.a : pa.z
puts "#{ pa.req_arg }#{ kw }"
end
method 4, 'a' => 2
method 4, 'z' => 2
~ > ruby sample/d.rb
42
42
<========< sample/e.rb >========>
~ > ruby -e'puts(IO::read(ARGV.shift))' sample/e.rb
require 'parseargs'
include ParseArgs
#
# a single, or list of types may be given and the argument of invocation must be
# one of those types as reports by '==='
#
def method(*a)
pa =
parseargs(a) {
req_arg 'number', 'types' => [Float, Fixnum]
}
p pa.number
end
method 42
method 42.0
method '42.0'
~ > ruby sample/e.rb
42
42.0
./lib/parseargs.rb:112:in `value=': value given not of type(Float,Fixnum) in 'number=' (TypeError)
from ./lib/parseargs.rb:296:in `parse'
from ./lib/parseargs.rb:291:in `each'
from ./lib/parseargs.rb:291:in `parse'
from ./lib/parseargs.rb:393:in `parseargs'
from ./lib/parseargs.rb:376:in `parseargs'
from sample/e.rb:11:in `method'
from sample/e.rb:20
<========< sample/f.rb >========>
~ > ruby -e'puts(IO::read(ARGV.shift))' sample/f.rb
require 'parseargs'
include ParseArgs
#
# failure of an argument to match a given type will cause coercion to be applied
# if specified. the coerce argument may be either a method name or a proc that
# receives the obj to be coerced. in either case the return value is used as
# the new argument.
#
def method(*a)
pa =
parseargs(a) {
arg :a, :types => Fixnum, :coerce => 'to_i'
kw :b, :types => Fixnum, :coerce => lambda{|obj| obj.to_i}
}
p [pa.a, pa.b]
end
method 4, :b => 2
method '4', :b => '2'
~ > ruby sample/f.rb
[4, 2]
[4, 2]
<========< sample/g.rb >========>
~ > ruby -e'puts(IO::read(ARGV.shift))' sample/g.rb
require 'parseargs'
include ParseArgs
#
# ducktyping is supported as a method name, or list of method names - all of
# which an argument must respond_to? in order for an exception not to be thrown.
# this is a very simple ducktype signature.
#
def method(*a)
pa =
parseargs(a) {
r_arg 'string', 'ducktype' => [:upcase, :downcase]
}
puts pa.string.upcase.downcase
end
method ['42']
~ > ruby sample/g.rb
42
<========< sample/h.rb >========>
~ > ruby -e'puts(IO::read(ARGV.shift))' sample/h.rb
require 'parseargs'
include ParseArgs
#
# a kind of ducktype 'coercion' - somthing i'm calling 'convincing' - may be
# applied in order to convince an object that it really can play a certain role.
# an argument may be 'convinced' via a module, which will be used to extend the
# object on the fly, or a block which is passed the object and expected to
# modify it's singleton class in such a way as to allow the object to become a
# valid argument
#
module M
def quack
2
end
end
def method(*a)
pa =
parseargs(a) {
ra 'a', 'ducktype' => :quack,
'convince' => lambda{|obj| class << obj; def quack; 4; end; end}
ra 'b', 'ducktype' => :quack,
'convince' => M
}
puts "#{ pa.a.quack }#{ pa.b.quack }"
end
method 'any ol', 'objects'
~ > ruby sample/h.rb
42
<========< sample/i.rb >========>
~ > ruby -e'puts(IO::read(ARGV.shift))' sample/i.rb
require 'parseargs'
#
# of course all this would be kind of silly for the simple cases shown - but it
# can become very powerful as a form of meta-programming aid or when many
# kewords are to be supported
#
class Command
include ParseArgs
KEYWORDS = %w(
verbose
quiet
log
help
info
force
recursive
stdin
stdout
stderr
)
PARSER =
ParseArgs:arser::new {
KEYWORDS.each{|kw| optional_keyword kw}
}
def initialize cmd
@cmd = cmd
end
def execute(*argv)
opts = PARSER.parse argv
p @cmd => opts.select{|k,v| not v.nil?}
end
def background(*argv)
opts = PARSER.parse argv
p @cmd => opts.select{|k,v| not v.nil?}
end
end
foo = Command::new 'foo.exe'
foo.execute 'verbose' => true, 'stdin' => 'input.txt'
bar = Command::new 'bar.exe'
bar.execute 'verbose' => false, 'stdout' => 'output.txt'
~ > ruby sample/i.rb
{"foo.exe"=>[["stdin", "input.txt"], ["verbose", true]]}
{"bar.exe"=>[["stdout", "output.txt"], ["verbose", false]]}
CAVEATS
this library is experimental.
enjoy.
-a
--
===============================================================================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| My religion is very simple. My religion is kindness.
| --Tenzin Gyatso
===============================================================================