facets 2.7.0 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/HISTORY.rdoc +135 -294
- data/MANIFEST +40 -91
- data/NOTES +1 -1
- data/README.rdoc +10 -8
- data/Rakefile +11 -34
- data/demo/{hook.rd → hook.rdoc} +2 -0
- data/demo/{scenario_require.rd → scenario_require.rdoc} +3 -0
- data/lib/core/facets-live.rb +7 -5
- data/lib/core/facets.rb +379 -359
- data/lib/core/facets/array/conjoin.rb +2 -2
- data/lib/core/facets/array/pad.rb +1 -1
- data/lib/core/facets/array/recursively.rb +2 -2
- data/lib/core/facets/array/splice.rb +1 -1
- data/lib/core/facets/binding/caller.rb +2 -4
- data/lib/core/facets/comparable/comparable.rb +2 -2
- data/lib/core/facets/dir/ascend.rb +3 -0
- data/lib/core/facets/dir/recurse.rb +4 -0
- data/lib/core/facets/duplicable.rb +6 -8
- data/lib/core/facets/enumerable/count.rb +22 -13
- data/lib/core/facets/enumerable/map_detect.rb +28 -0
- data/lib/core/facets/enumerable/mash.rb +13 -5
- data/lib/core/facets/enumerable/per.rb +3 -1
- data/lib/core/facets/hash/count.rb +14 -0
- data/lib/core/facets/hash/data.rb +14 -0
- data/lib/core/facets/kernel/__method__.rb +1 -1
- data/lib/core/facets/kernel/d.rb +9 -8
- data/lib/core/facets/kernel/eigenclass.rb +20 -0
- data/lib/core/facets/kernel/extend.rb +10 -0
- data/lib/core/facets/kernel/instance_class.rb +1 -0
- data/lib/core/facets/kernel/instance_variables.rb +6 -6
- data/lib/core/facets/kernel/meta_alias.rb +18 -0
- data/lib/core/facets/kernel/meta_class.rb +17 -0
- data/lib/core/facets/kernel/meta_def.rb +18 -0
- data/lib/core/facets/kernel/meta_eval.rb +18 -0
- data/lib/core/facets/kernel/object_hexid.rb +21 -6
- data/lib/core/facets/kernel/object_state.rb +4 -2
- data/lib/core/facets/kernel/populate.rb +3 -1
- data/lib/core/facets/kernel/with.rb +1 -1
- data/lib/core/facets/metaid.rb +6 -93
- data/lib/core/facets/module/class_def.rb +2 -0
- data/lib/core/facets/module/extend.rb +10 -11
- data/lib/core/facets/module/is.rb +5 -5
- data/lib/core/facets/module/module_def.rb +31 -0
- data/lib/core/facets/string/camelcase.rb +14 -12
- data/lib/core/facets/string/cleanlines.rb +35 -0
- data/lib/core/facets/string/edit_distance.rb +62 -0
- data/lib/core/facets/string/indent.rb +86 -4
- data/lib/core/facets/string/index_all.rb +24 -0
- data/lib/core/facets/string/lines.rb +3 -6
- data/lib/core/facets/string/margin.rb +2 -1
- data/lib/core/facets/string/newlines.rb +35 -0
- data/lib/core/facets/string/op_div.rb +14 -0
- data/lib/core/facets/string/range.rb +2 -22
- data/lib/core/facets/string/range_all.rb +1 -0
- data/lib/core/facets/string/range_of_line.rb +1 -0
- data/lib/core/facets/string/similarity.rb +92 -0
- data/lib/core/facets/string/start_with.rb +6 -6
- data/lib/core/facets/string/titlecase.rb +1 -1
- data/lib/more/facets/basicobject.rb +16 -15
- data/lib/more/facets/blankslate.rb +8 -0
- data/lib/more/facets/class_extend.rb +126 -1
- data/lib/more/facets/continuation.rb +53 -54
- data/lib/more/facets/dictionary.rb +9 -63
- data/lib/more/facets/erb.rb +63 -0
- data/lib/more/facets/filelist.rb +5 -5
- data/lib/more/facets/hashbuilder.rb +101 -0
- data/lib/more/facets/inheritor.rb +36 -45
- data/lib/more/facets/ini.rb +267 -0
- data/lib/more/facets/instance_eval.rb +4 -4
- data/lib/more/facets/ioredirect.rb +7 -60
- data/lib/more/facets/linkedlist.rb +195 -0
- data/lib/more/facets/matcher.rb +140 -0
- data/lib/more/facets/memoizer.rb +64 -0
- data/lib/more/facets/methodspace.rb +9 -4
- data/lib/more/facets/module/class_extend.rb +2 -121
- data/lib/more/facets/ostruct.rb +9 -9
- data/lib/more/facets/pathlist.rb +1 -9
- data/lib/more/facets/pathname.rb +11 -4
- data/lib/more/facets/plugin_manager.rb +50 -0
- data/lib/more/facets/random.rb +25 -3
- data/lib/more/facets/roman.rb +174 -0
- data/lib/more/facets/semaphore.rb +92 -0
- data/lib/more/facets/shellwords.rb +21 -48
- data/lib/more/facets/succ.rb +1 -1
- data/meta/{modified → released} +0 -0
- data/meta/repository +1 -0
- data/meta/suite +1 -0
- data/meta/version +1 -1
- data/script/conflicts +63 -0
- data/script/methods +49 -0
- data/test/core/binding/test_caller.rb +11 -4
- data/test/core/enumerable/test_count.rb +19 -10
- data/test/core/enumerable/test_map_detect.rb +75 -0
- data/test/core/enumerable/test_take.rb +1 -1
- data/test/core/kernel/test_object_hexid.rb +2 -1
- data/test/core/proc/test_to_method.rb +1 -1
- data/test/core/string/test_cleanlines.rb +11 -0
- data/test/core/string/test_indent.rb +66 -4
- data/test/core/string/test_lines.rb +2 -1
- data/test/core/string/test_newlines.rb +13 -0
- data/test/core/time/test_change.rb +1 -1
- data/test/core/time/test_stamp.rb +4 -7
- data/test/core/unboundmethod/test_name.rb +1 -1
- data/test/more/test_basicobject.rb +1 -20
- data/test/more/test_class_extend.rb +7 -0
- data/test/more/test_continuation.rb +8 -6
- data/test/more/test_inheritor.rb +12 -6
- data/test/more/test_random.rb +19 -10
- data/test/more/test_shellwords.rb +33 -0
- metadata +60 -31
- data/TODO +0 -5
- data/doc/README.core +0 -102
- data/doc/README.more +0 -61
- data/doc/manual/about.rb +0 -47
- data/doc/manual/annotations.rdoc +0 -60
- data/doc/manual/associations.rdoc +0 -55
- data/doc/manual/blockups.rdoc +0 -101
- data/doc/manual/capsule.rdoc +0 -34
- data/doc/manual/command.rdoc +0 -177
- data/doc/manual/core.rdoc +0 -37
- data/doc/manual/faq.rdoc +0 -32
- data/doc/manual/typecast.html +0 -112
- data/lib/more/facets/capsule.rb +0 -258
- data/lib/more/facets/coroutine.rb +0 -159
- data/lib/more/facets/enumerablepass.rb +0 -3
- data/lib/more/facets/fileable.rb +0 -162
- data/lib/more/facets/progressbar.rb +0 -253
- data/lib/more/facets/recorder.rb +0 -108
- data/meta/releases +0 -14
- data/test/more/test_coroutine.rb +0 -46
@@ -0,0 +1,50 @@
|
|
1
|
+
# = Plugin Manger
|
2
|
+
#
|
3
|
+
# Find plugins easily.
|
4
|
+
#
|
5
|
+
# NOTE: This is likely to be replaced with
|
6
|
+
# a more generic means of finding libraries.
|
7
|
+
#
|
8
|
+
module PluginManager
|
9
|
+
extend self
|
10
|
+
|
11
|
+
# Find plugins, searching through standard $LOAD_PATH,
|
12
|
+
# Roll Libraries and RubyGems.
|
13
|
+
#
|
14
|
+
# +match+ is a file glob for finding plugins.
|
15
|
+
#
|
16
|
+
# PluginManager.find('syckles/*')
|
17
|
+
#
|
18
|
+
def find(match)
|
19
|
+
plugins = []
|
20
|
+
# Standard $LOAD_PATH
|
21
|
+
$LOAD_PATH.uniq.each do |path|
|
22
|
+
list = Dir.glob(File.join(path, match))
|
23
|
+
#dirs = dirs.select{ |d| File.directory?(d) }
|
24
|
+
list = list.map{ |d| d.chomp('/') }
|
25
|
+
plugins.concat(list)
|
26
|
+
end
|
27
|
+
# ROLL (load latest versions only)
|
28
|
+
if defined?(::Roll)
|
29
|
+
::Roll::Library.ledger.each do |name, lib|
|
30
|
+
lib = lib.sort.first if Array===lib
|
31
|
+
lib.load_path.each do |path|
|
32
|
+
find = File.join(lib.location, path, match)
|
33
|
+
list = Dir.glob(find)
|
34
|
+
list = list.map{ |d| d.chomp('/') }
|
35
|
+
plugins.concat(list)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
# RubyGems (load latest versions only)
|
40
|
+
if defined?(::Gem)
|
41
|
+
Gem.latest_load_paths do |path|
|
42
|
+
list = Dir.glob(File.join(path, match))
|
43
|
+
list = list.map{ |d| d.chomp('/') }
|
44
|
+
plugins.concat(list)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
plugins
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
data/lib/more/facets/random.rb
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
#
|
3
3
|
# Randomization core extension methods.
|
4
4
|
#
|
5
|
-
# This library extends Object, Array, String and
|
5
|
+
# This library extends Object, Array, String, Hash, and Range with randomization
|
6
6
|
# methods. Most of the methods are of one of two kinds. Either they "pick"
|
7
|
-
# a random element from the reciever or they randomly "shuffle" the
|
7
|
+
# a random element from the reciever or they randomly "shuffle" the receiver.
|
8
8
|
#
|
9
9
|
# The most common example is Array#shuffle, which simply randmomizes the
|
10
10
|
# order of an array's elements.
|
@@ -66,6 +66,8 @@ module Random
|
|
66
66
|
def self.append_features(mod)
|
67
67
|
if mod == ::Object
|
68
68
|
mod.send(:include, Random::Object)
|
69
|
+
elsif mod == ::Range
|
70
|
+
mod.send(:include, Random::Range)
|
69
71
|
elsif mod == ::Array
|
70
72
|
mod.send(:include, Random::Array)
|
71
73
|
elsif mod == ::Hash
|
@@ -97,9 +99,25 @@ module Random
|
|
97
99
|
|
98
100
|
#
|
99
101
|
|
102
|
+
module Range
|
103
|
+
|
104
|
+
# Return a random element from the range.
|
105
|
+
#
|
106
|
+
# (1..4).at_rand #=> 2
|
107
|
+
# (1..4).at_rand #=> 4
|
108
|
+
#
|
109
|
+
def at_rand
|
110
|
+
array = to_a
|
111
|
+
array.at(Random.number(array.size))
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
#
|
117
|
+
|
100
118
|
module Array
|
101
119
|
|
102
|
-
# Return a random element
|
120
|
+
# Return a random element from the array.
|
103
121
|
#
|
104
122
|
# [1, 2, 3, 4].at_rand #=> 2
|
105
123
|
# [1, 2, 3, 4].at_rand #=> 4
|
@@ -437,6 +455,10 @@ class Object
|
|
437
455
|
include Random
|
438
456
|
end
|
439
457
|
|
458
|
+
class Range
|
459
|
+
include Random
|
460
|
+
end
|
461
|
+
|
440
462
|
class Array
|
441
463
|
include Random
|
442
464
|
end
|
@@ -0,0 +1,174 @@
|
|
1
|
+
# = TITLE:
|
2
|
+
# Roman Numerals
|
3
|
+
#
|
4
|
+
# = SYNOPSIS:
|
5
|
+
# Generates roman numerals from integers and vice-versa.
|
6
|
+
#
|
7
|
+
# = NOTES:
|
8
|
+
# A response to Ruby Quiz of the Week #22 - Roman Numerals [ruby-talk:132925]
|
9
|
+
#
|
10
|
+
# = AUTHORS:
|
11
|
+
# - Dave Burt <dave at burt.id.au>
|
12
|
+
# - Trans
|
13
|
+
|
14
|
+
module English #:nodoc:
|
15
|
+
|
16
|
+
# Contains methods to convert integers to roman numeral strings and vice-versa.
|
17
|
+
|
18
|
+
module RomanNumerals
|
19
|
+
|
20
|
+
# The largest integer representable as a roman
|
21
|
+
# numerable by this module.
|
22
|
+
|
23
|
+
MAX = 3999
|
24
|
+
|
25
|
+
# Stolen from O'Reilly's Perl Cookbook 6.23. Regular Expression Grabbag.
|
26
|
+
|
27
|
+
REGEXP = /^M*(D?C{0,3}|C[DM])(L?X{0,3}|X[LC])(V?I{0,3}|I[VX])$/i
|
28
|
+
|
29
|
+
#
|
30
|
+
|
31
|
+
SYMBOLS = [ "M", "D", "C", "L", "X", "V", "I" ]
|
32
|
+
NUMBERS = [ 1000, 500, 100, 50, 10, 5, 1 ]
|
33
|
+
|
34
|
+
|
35
|
+
# Maps roman numeral digits to their integer values.
|
36
|
+
# {
|
37
|
+
# 'I' => 1,
|
38
|
+
# 'V' => 5,
|
39
|
+
# 'X' => 10,
|
40
|
+
# 'L' => 50,
|
41
|
+
# 'C' => 100,
|
42
|
+
# 'D' => 500,
|
43
|
+
# 'M' => 1000,
|
44
|
+
# }
|
45
|
+
|
46
|
+
TABLE = Hash[*SYMBOLS.zip(NUMBERS).flatten]
|
47
|
+
|
48
|
+
#
|
49
|
+
|
50
|
+
PAIR_SYMBOLS = [ "CM", "CD", "XC", "XL", "IX", "IV", "I" ]
|
51
|
+
PAIR_NUMBERS = [ 900, 400, 90, 40, 9, 4, 1 ]
|
52
|
+
|
53
|
+
# {
|
54
|
+
# 'CM' => 900,
|
55
|
+
# 'CD' => 400,
|
56
|
+
# 'XC' => 90,
|
57
|
+
# 'XL' => 40,
|
58
|
+
# 'IX' => 9,
|
59
|
+
# 'IV' => 4
|
60
|
+
# }
|
61
|
+
|
62
|
+
PAIR_TABLE = Hash[*PAIR_SYMBOLS.zip(PAIR_NUMBERS).flatten]
|
63
|
+
|
64
|
+
#
|
65
|
+
|
66
|
+
LOOKUP = TABLE.invert.merge(PAIR_TABLE.invert)
|
67
|
+
|
68
|
+
|
69
|
+
class << self
|
70
|
+
|
71
|
+
# Converts +integer+ to a roman numeral.
|
72
|
+
|
73
|
+
def from_integer(integer)
|
74
|
+
return nil if integer < 0 || integer > MAX
|
75
|
+
|
76
|
+
r = integer # remainder
|
77
|
+
y = '' # result
|
78
|
+
|
79
|
+
NUMBERS.each do |n|
|
80
|
+
while r >= n
|
81
|
+
r -= n
|
82
|
+
y += LOOKUP[n]
|
83
|
+
end
|
84
|
+
break if r <= 0
|
85
|
+
end
|
86
|
+
|
87
|
+
return y
|
88
|
+
end
|
89
|
+
|
90
|
+
alias_method :roman, :from_integer
|
91
|
+
|
92
|
+
# Converts +roman_string+, a roman numeral, to an integer
|
93
|
+
|
94
|
+
def to_integer(roman_string)
|
95
|
+
return nil unless roman_string.is_roman_numeral?
|
96
|
+
|
97
|
+
l = nil # last
|
98
|
+
i = 0 # integer result
|
99
|
+
|
100
|
+
c = roman_string.to_s.upcase.split(//).reverse
|
101
|
+
|
102
|
+
c.each do |d|
|
103
|
+
if v = TABLE[d]
|
104
|
+
if l && l > v
|
105
|
+
i -= v
|
106
|
+
else
|
107
|
+
i += v
|
108
|
+
end
|
109
|
+
l = v
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
return i
|
114
|
+
end
|
115
|
+
|
116
|
+
alias_method :arabic, :to_integer
|
117
|
+
|
118
|
+
# Returns true iif +string+ is a roman numeral.
|
119
|
+
|
120
|
+
def is_roman_numeral?(string)
|
121
|
+
REGEXP =~ string
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
end # module English
|
129
|
+
|
130
|
+
|
131
|
+
class Integer
|
132
|
+
|
133
|
+
def roman
|
134
|
+
English::RomanNumerals.roman(self) || ''
|
135
|
+
end
|
136
|
+
|
137
|
+
# Converts this integer to a roman numeral.
|
138
|
+
|
139
|
+
def to_s_roman
|
140
|
+
English::RomanNumerals.from_integer(self) || ''
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
|
146
|
+
class String
|
147
|
+
|
148
|
+
# Considers string a roman numeral numeral,
|
149
|
+
# and converts it to the corresponding integer.
|
150
|
+
|
151
|
+
def to_i_roman
|
152
|
+
English::RomanNumerals.to_integer(self)
|
153
|
+
end
|
154
|
+
|
155
|
+
# Returns true iif the subject is a roman numeral.
|
156
|
+
|
157
|
+
def is_roman_numeral?
|
158
|
+
English::RomanNumerals.is_roman_numeral?(self)
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
162
|
+
|
163
|
+
|
164
|
+
# # Quiz solution: filter that swaps roman and arabic numbers
|
165
|
+
# if __FILE__ == $0
|
166
|
+
# ARGF.each do |line|
|
167
|
+
# line.chomp!
|
168
|
+
# if line.is_roman_numeral?
|
169
|
+
# puts line.to_i_roman
|
170
|
+
# else
|
171
|
+
# puts line.to_i.to_s_roman
|
172
|
+
# end
|
173
|
+
# end
|
174
|
+
# end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# = Semaphore
|
2
|
+
#
|
3
|
+
# Technically a semaphore is simply an integer variable which
|
4
|
+
# has an execution queue associated with it.
|
5
|
+
#
|
6
|
+
# == Authors
|
7
|
+
#
|
8
|
+
# * Fukumoto
|
9
|
+
#
|
10
|
+
# = Copying
|
11
|
+
#
|
12
|
+
# Copyright (c) 2005 Fukumoto
|
13
|
+
#
|
14
|
+
# Ruby License
|
15
|
+
#
|
16
|
+
# This module is free software. You may use, modify, and/or redistribute this
|
17
|
+
# software under the same terms as Ruby.
|
18
|
+
#
|
19
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT
|
20
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
21
|
+
# FOR A PARTICULAR PURPOSE.
|
22
|
+
|
23
|
+
|
24
|
+
# = Semaphore
|
25
|
+
#
|
26
|
+
# Technically a semaphore is simply an integer variable which
|
27
|
+
# has an execution queue associated with it.
|
28
|
+
#
|
29
|
+
class Semaphore
|
30
|
+
|
31
|
+
def initialize(initvalue = 0)
|
32
|
+
@counter = initvalue
|
33
|
+
@waiting_list = []
|
34
|
+
end
|
35
|
+
|
36
|
+
def wait
|
37
|
+
Thread.critical = true
|
38
|
+
if (@counter -= 1) < 0
|
39
|
+
@waiting_list.push(Thread.current)
|
40
|
+
Thread.stop
|
41
|
+
end
|
42
|
+
self
|
43
|
+
ensure
|
44
|
+
Thread.critical = false
|
45
|
+
end
|
46
|
+
|
47
|
+
def signal
|
48
|
+
Thread.critical = true
|
49
|
+
begin
|
50
|
+
if (@counter += 1) <= 0
|
51
|
+
t = @waiting_list.shift
|
52
|
+
t.wakeup if t
|
53
|
+
end
|
54
|
+
rescue ThreadError
|
55
|
+
retry
|
56
|
+
end
|
57
|
+
self
|
58
|
+
ensure
|
59
|
+
Thread.critical = false
|
60
|
+
end
|
61
|
+
|
62
|
+
alias_method( :down, :wait )
|
63
|
+
alias_method( :up, :signal )
|
64
|
+
alias_method( :p, :wait )
|
65
|
+
alias_method( :v, :signal )
|
66
|
+
|
67
|
+
def exclusive
|
68
|
+
wait
|
69
|
+
yield
|
70
|
+
ensure
|
71
|
+
signal
|
72
|
+
end
|
73
|
+
|
74
|
+
alias_method( :synchronize, :exclusive )
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
# _____ _
|
80
|
+
# |_ _|__ ___| |_
|
81
|
+
# | |/ _ \/ __| __|
|
82
|
+
# | | __/\__ \ |_
|
83
|
+
# |_|\___||___/\__|
|
84
|
+
#
|
85
|
+
|
86
|
+
# TODO
|
87
|
+
|
88
|
+
=begin #test
|
89
|
+
|
90
|
+
require 'test/unit'
|
91
|
+
|
92
|
+
=end
|
@@ -1,24 +1,3 @@
|
|
1
|
-
# = Shellwords Extended
|
2
|
-
#
|
3
|
-
# Adds extensions to Shellwords, namely #escape.
|
4
|
-
#
|
5
|
-
# == Authors
|
6
|
-
#
|
7
|
-
# * Thomas Sawuer
|
8
|
-
#
|
9
|
-
# == Copying
|
10
|
-
#
|
11
|
-
# Copyright (c) 2007 Thomas Sawyer
|
12
|
-
#
|
13
|
-
# Ruby License
|
14
|
-
#
|
15
|
-
# This module is free software. You may use, modify, and/or redistribute this
|
16
|
-
# software under the same terms as Ruby.
|
17
|
-
#
|
18
|
-
# This program is distributed in the hope that it will be useful, but WITHOUT
|
19
|
-
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
20
|
-
# FOR A PARTICULAR PURPOSE.
|
21
|
-
|
22
1
|
require 'shellwords'
|
23
2
|
|
24
3
|
module Shellwords
|
@@ -34,56 +13,50 @@ module Shellwords
|
|
34
13
|
|
35
14
|
end
|
36
15
|
|
37
|
-
|
38
16
|
class Array
|
39
17
|
|
40
18
|
# Convert an array into command line parameters.
|
41
19
|
# The array is accepted in the format of Ruby
|
42
20
|
# method arguments --ie. [arg1, arg2, ..., hash]
|
43
|
-
|
44
|
-
def
|
45
|
-
|
46
|
-
|
47
|
-
|
21
|
+
#
|
22
|
+
def shellwords
|
23
|
+
opts, args = *flatten.partition{ |e| Hash === e }
|
24
|
+
opts = opts.inject({}){ |m,h| m.update(h); m }
|
25
|
+
opts.shellwords + args
|
48
26
|
end
|
49
27
|
|
50
|
-
def
|
51
|
-
|
28
|
+
def shelljoin
|
29
|
+
Shellwords.shelljoin(shellwords)
|
52
30
|
end
|
53
31
|
|
54
|
-
# Original name.
|
55
|
-
alias_method :to_console, :to_shell
|
56
32
|
end
|
57
33
|
|
58
|
-
|
59
34
|
class Hash
|
60
35
|
|
61
|
-
#
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
def to_shellwords
|
66
|
-
flags = collect do |f,v|
|
36
|
+
#
|
37
|
+
def shellwords
|
38
|
+
argv = []
|
39
|
+
each do |f,v|
|
67
40
|
m = f.to_s.size == 1 ? '-' : '--'
|
68
41
|
case v
|
42
|
+
when false, nil
|
69
43
|
when Array
|
70
|
-
v.
|
44
|
+
v.each do |e|
|
45
|
+
argv << %[#{m}#{f}="#{e}"]
|
46
|
+
end
|
71
47
|
when true
|
72
|
-
|
73
|
-
when false, nil
|
74
|
-
''
|
48
|
+
argv << %[#{m}#{f}]
|
75
49
|
else
|
76
|
-
|
50
|
+
argv << %[#{m}#{f}="#{v}"]
|
77
51
|
end
|
78
52
|
end
|
79
|
-
|
53
|
+
argv
|
80
54
|
end
|
81
55
|
|
82
|
-
|
83
|
-
|
56
|
+
#
|
57
|
+
def shelljoin
|
58
|
+
shellwords.shelljoin
|
84
59
|
end
|
85
60
|
|
86
|
-
# Original name.
|
87
|
-
alias_method :to_console, :to_shell
|
88
61
|
end
|
89
62
|
|