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
@@ -1,159 +0,0 @@
|
|
1
|
-
# = Coroutine
|
2
|
-
#
|
3
|
-
# Coroutines are program components like subroutines. Coroutines are more
|
4
|
-
# generic and flexible than subroutines, but are less widely used in
|
5
|
-
# practice. Coroutines were first introduced natively in Simula.
|
6
|
-
# Coroutines are well suited for implementing more familiar program
|
7
|
-
# components such as cooperative tasks, iterators, infinite lists, and pipes.
|
8
|
-
#
|
9
|
-
# This mixin solely depends on method read(n), which must be
|
10
|
-
# defined in the class/module where you mix in this module.
|
11
|
-
#
|
12
|
-
# == Usage
|
13
|
-
#
|
14
|
-
# count = (ARGV.shift || 1000).to_i
|
15
|
-
# input = (1..count).map { (rand * 10000).round.to_f / 100}
|
16
|
-
#
|
17
|
-
# Producer = Coroutine.new do |me|
|
18
|
-
# loop do
|
19
|
-
# 1.upto(6) do
|
20
|
-
# me[:last_input] = input.shift
|
21
|
-
# me.resume(Printer)
|
22
|
-
# end
|
23
|
-
# input.shift # discard every seventh input number
|
24
|
-
# end
|
25
|
-
# end
|
26
|
-
# Printer = Coroutine.new do |me|
|
27
|
-
# loop do
|
28
|
-
# 1.upto(8) do
|
29
|
-
# me.resume(Producer)
|
30
|
-
# if Producer[:last_input]
|
31
|
-
# print Producer[:last_input], "\t"
|
32
|
-
# Producer[:last_input] = nil
|
33
|
-
# end
|
34
|
-
# me.resume(Controller)
|
35
|
-
# end
|
36
|
-
# puts
|
37
|
-
# end
|
38
|
-
# end
|
39
|
-
#
|
40
|
-
# Controller = Coroutine.new do |me|
|
41
|
-
# until input.empty? do
|
42
|
-
# me.resume(Printer)
|
43
|
-
# end
|
44
|
-
# end
|
45
|
-
#
|
46
|
-
# Controller.run
|
47
|
-
#
|
48
|
-
# == Authors
|
49
|
-
#
|
50
|
-
# * Florian Frank
|
51
|
-
#
|
52
|
-
# == Copying
|
53
|
-
#
|
54
|
-
# Copyright (c) 2005 Florian Frank
|
55
|
-
#
|
56
|
-
# Ruby License
|
57
|
-
#
|
58
|
-
# This module is free software. You may use, modify, and/or redistribute this
|
59
|
-
# software under the same terms as Ruby.
|
60
|
-
#
|
61
|
-
# This program is distributed in the hope that it will be useful, but WITHOUT
|
62
|
-
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
63
|
-
# FOR A PARTICULAR PURPOSE.
|
64
|
-
|
65
|
-
|
66
|
-
# = Coroutine
|
67
|
-
#
|
68
|
-
# Coroutines are program components like subroutines. Coroutines are more
|
69
|
-
# generic and flexible than subroutines, but are less widely used in
|
70
|
-
# practice. Coroutines were first introduced natively in Simula.
|
71
|
-
# Coroutines are well suited for implementing more familiar program
|
72
|
-
# components such as cooperative tasks, iterators, infinite lists, and pipes.
|
73
|
-
#
|
74
|
-
# This mixin solely depends on method read(n), which must be
|
75
|
-
# defined in the class/module where you mix in this module.
|
76
|
-
#
|
77
|
-
# == Usage
|
78
|
-
#
|
79
|
-
# count = (ARGV.shift || 1000).to_i
|
80
|
-
# input = (1..count).map { (rand * 10000).round.to_f / 100}
|
81
|
-
#
|
82
|
-
# Producer = Coroutine.new do |me|
|
83
|
-
# loop do
|
84
|
-
# 1.upto(6) do
|
85
|
-
# me[:last_input] = input.shift
|
86
|
-
# me.resume(Printer)
|
87
|
-
# end
|
88
|
-
# input.shift # discard every seventh input number
|
89
|
-
# end
|
90
|
-
# end
|
91
|
-
# Printer = Coroutine.new do |me|
|
92
|
-
# loop do
|
93
|
-
# 1.upto(8) do
|
94
|
-
# me.resume(Producer)
|
95
|
-
# if Producer[:last_input]
|
96
|
-
# print Producer[:last_input], "\t"
|
97
|
-
# Producer[:last_input] = nil
|
98
|
-
# end
|
99
|
-
# me.resume(Controller)
|
100
|
-
# end
|
101
|
-
# puts
|
102
|
-
# end
|
103
|
-
# end
|
104
|
-
#
|
105
|
-
# Controller = Coroutine.new do |me|
|
106
|
-
# until input.empty? do
|
107
|
-
# me.resume(Printer)
|
108
|
-
# end
|
109
|
-
# end
|
110
|
-
#
|
111
|
-
# Controller.run
|
112
|
-
#
|
113
|
-
class Coroutine
|
114
|
-
|
115
|
-
def initialize(data = {})
|
116
|
-
@stopped = nil
|
117
|
-
@data = data
|
118
|
-
callcc do |@continue|
|
119
|
-
return
|
120
|
-
end
|
121
|
-
yield self
|
122
|
-
stop
|
123
|
-
end
|
124
|
-
|
125
|
-
attr_reader :stopped
|
126
|
-
|
127
|
-
def run
|
128
|
-
callcc do |@stopped|
|
129
|
-
continue
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
def stop
|
134
|
-
@stopped.call
|
135
|
-
end
|
136
|
-
|
137
|
-
def resume(other)
|
138
|
-
callcc do |@continue|
|
139
|
-
other.continue(self)
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
def continue(from = nil)
|
144
|
-
@stopped = from.stopped if not @stopped and from
|
145
|
-
@continue.call
|
146
|
-
end
|
147
|
-
|
148
|
-
def [](name)
|
149
|
-
@data[name]
|
150
|
-
end
|
151
|
-
|
152
|
-
def []=(name, value)
|
153
|
-
@data[name] = value
|
154
|
-
end
|
155
|
-
|
156
|
-
protected :stopped, :continue
|
157
|
-
|
158
|
-
end
|
159
|
-
|
data/lib/more/facets/fileable.rb
DELETED
@@ -1,162 +0,0 @@
|
|
1
|
-
# = Fileable
|
2
|
-
#
|
3
|
-
# Make File-esque classes. Fileable makes it easy to
|
4
|
-
# create classes that can load from files.
|
5
|
-
#
|
6
|
-
# Class level mixin for loading/opening file classes.
|
7
|
-
# You will generally want to use extend with this.
|
8
|
-
#
|
9
|
-
# NOTE: This is an expiremental library, and is still
|
10
|
-
# undergoing revision.
|
11
|
-
#
|
12
|
-
# = Copying
|
13
|
-
#
|
14
|
-
# Copyright (c) 2007 Thomas Sawyer
|
15
|
-
#
|
16
|
-
# Ruby License
|
17
|
-
#
|
18
|
-
# This module is free software. You may use, modify, and/or redistribute this
|
19
|
-
# software under the same terms as Ruby.
|
20
|
-
#
|
21
|
-
# This program is distributed in the hope that it will be useful, but WITHOUT
|
22
|
-
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
23
|
-
# FOR A PARTICULAR PURPOSE.
|
24
|
-
#
|
25
|
-
# == Authors
|
26
|
-
#
|
27
|
-
# * Thomas Sawyer
|
28
|
-
#
|
29
|
-
# == Todo
|
30
|
-
#
|
31
|
-
# * Consider cachable version of Fileable.
|
32
|
-
|
33
|
-
|
34
|
-
# = Fileable
|
35
|
-
#
|
36
|
-
# Make File-esque classes. Fileable makes it easy to
|
37
|
-
# create classes that can load from files.
|
38
|
-
#
|
39
|
-
# Class level mixin for loading/opening file classes.
|
40
|
-
# You will generally want to use extend with this.
|
41
|
-
#
|
42
|
-
# NOTE: This is an expiremental library, and is still
|
43
|
-
# undergoing revision.
|
44
|
-
#
|
45
|
-
#
|
46
|
-
module Fileable
|
47
|
-
|
48
|
-
# When included extend DSL too.
|
49
|
-
|
50
|
-
def self.included(base)
|
51
|
-
base.extend DSL
|
52
|
-
end
|
53
|
-
|
54
|
-
# Store raw content of file.
|
55
|
-
|
56
|
-
#attr_reader :content
|
57
|
-
|
58
|
-
# New fileable object. By default this is called
|
59
|
-
# by #read passing the file contents. Override it
|
60
|
-
# if need is differnt.
|
61
|
-
|
62
|
-
def initialize(content)
|
63
|
-
@content = content
|
64
|
-
end
|
65
|
-
|
66
|
-
# Override this if reading is differnt.
|
67
|
-
|
68
|
-
def read(file)
|
69
|
-
self.file = file if defined?(:file=)
|
70
|
-
initialize(File.read(file))
|
71
|
-
end
|
72
|
-
|
73
|
-
#
|
74
|
-
module DSL
|
75
|
-
|
76
|
-
# While this doesn't allpy to classes, for modules
|
77
|
-
# it is needed to keep the DSL inheritance going.
|
78
|
-
|
79
|
-
def included(base)
|
80
|
-
base.extend DSL
|
81
|
-
end
|
82
|
-
|
83
|
-
# Override this with the name or name-glob of
|
84
|
-
# the default file. If no default, return nil.
|
85
|
-
|
86
|
-
def filename; nil; end
|
87
|
-
|
88
|
-
# Load from file(s).
|
89
|
-
|
90
|
-
def open(path=nil)
|
91
|
-
file = file(path)
|
92
|
-
if file
|
93
|
-
fobj = new
|
94
|
-
fobj.send(:read, file)
|
95
|
-
return fobj
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
# An initializer that can take either a File, Pathname
|
100
|
-
# or raw data. This works much like YAML::load does.
|
101
|
-
# Unlike +open+, +load+ requires an exact path parameter.
|
102
|
-
|
103
|
-
def load(path_or_data)
|
104
|
-
case path_or_data
|
105
|
-
when File
|
106
|
-
open(path_or_data.path)
|
107
|
-
when Pathname
|
108
|
-
open(path_or_data.realpath)
|
109
|
-
else
|
110
|
-
new(path_or_data)
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
# Lookup file.
|
115
|
-
|
116
|
-
def lookup(name=nil)
|
117
|
-
file = locate(name)
|
118
|
-
file ? open(file) : nil #raise LoadError
|
119
|
-
end
|
120
|
-
|
121
|
-
# Locate file (case insensitive).
|
122
|
-
|
123
|
-
def locate(name=nil)
|
124
|
-
name ||= filename
|
125
|
-
raise LoadError unless name
|
126
|
-
Dir.ascend(Dir.pwd) do |dir|
|
127
|
-
match = File.join(dir, name)
|
128
|
-
files = Dir.glob(match, File::FNM_CASEFOLD)
|
129
|
-
if file = files[0]
|
130
|
-
return file
|
131
|
-
end
|
132
|
-
end
|
133
|
-
return nil
|
134
|
-
end
|
135
|
-
|
136
|
-
# Find file. The +path+ has to be either the
|
137
|
-
# exact path or the directory where a
|
138
|
-
# standard-named file resides.
|
139
|
-
|
140
|
-
def file(path=nil)
|
141
|
-
if !path
|
142
|
-
raise LoadError unless filename
|
143
|
-
path = filename
|
144
|
-
elsif File.directory?(path)
|
145
|
-
raise LoadError unless filename
|
146
|
-
path = File.join(path, filename)
|
147
|
-
end
|
148
|
-
if file = Dir.glob(path, File::FNM_CASEFOLD)[0]
|
149
|
-
File.expand_path(file)
|
150
|
-
else
|
151
|
-
raise Errno::ENOENT
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
# Load cache. PackageInfo is multiton when loaded by file.
|
156
|
-
|
157
|
-
def load_cache
|
158
|
-
@load_cache ||= {}
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
@@ -1,253 +0,0 @@
|
|
1
|
-
# = Progressbar
|
2
|
-
#
|
3
|
-
# ProgressBar is a text-based progressbar library.
|
4
|
-
#
|
5
|
-
# == Usage
|
6
|
-
#
|
7
|
-
# pbar = ProgressBar.new( "Demo", 100 )
|
8
|
-
# 100.times { pbar.inc }
|
9
|
-
# pbar.finish
|
10
|
-
#
|
11
|
-
# == Copying
|
12
|
-
#
|
13
|
-
# Copyright (C) 2001 Satoru Takabayashi
|
14
|
-
#
|
15
|
-
# Ruby License
|
16
|
-
#
|
17
|
-
# This module is free software. You may use, modify, and/or redistribute this
|
18
|
-
# software under the same terms as Ruby.
|
19
|
-
#
|
20
|
-
# This program is distributed in the hope that it will be useful, but WITHOUT
|
21
|
-
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
22
|
-
# FOR A PARTICULAR PURPOSE.
|
23
|
-
#
|
24
|
-
# == Author
|
25
|
-
#
|
26
|
-
# * Satoru Takabayashi
|
27
|
-
|
28
|
-
# = ProgressBar
|
29
|
-
#
|
30
|
-
# ProgressBar is a text-based progressbar library.
|
31
|
-
#
|
32
|
-
# pbar = ProgressBar.new( "Demo", 100 )
|
33
|
-
# 100.times { pbar.inc }
|
34
|
-
# pbar.finish
|
35
|
-
#
|
36
|
-
class ProgressBar
|
37
|
-
|
38
|
-
def initialize(title, total, out = STDERR)
|
39
|
-
@title = title
|
40
|
-
@total = total
|
41
|
-
@out = out
|
42
|
-
@bar_length = 80
|
43
|
-
@bar_mark = "o"
|
44
|
-
@total_overflow = true
|
45
|
-
@current = 0
|
46
|
-
@previous = 0
|
47
|
-
@is_finished = false
|
48
|
-
@start_time = Time.now
|
49
|
-
@format = "%-14s %3d%% %s %s"
|
50
|
-
@format_arguments = [:title, :percentage, :bar, :stat]
|
51
|
-
show_progress
|
52
|
-
end
|
53
|
-
|
54
|
-
private
|
55
|
-
def convert_bytes (bytes)
|
56
|
-
if bytes < 1024
|
57
|
-
sprintf("%6dB", bytes)
|
58
|
-
elsif bytes < 1024 * 1000 # 1000kb
|
59
|
-
sprintf("%5.1fKB", bytes.to_f / 1024)
|
60
|
-
elsif bytes < 1024 * 1024 * 1000 # 1000mb
|
61
|
-
sprintf("%5.1fMB", bytes.to_f / 1024 / 1024)
|
62
|
-
else
|
63
|
-
sprintf("%5.1fGB", bytes.to_f / 1024 / 1024 / 1024)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def transfer_rate
|
68
|
-
bytes_per_second = @current.to_f / (Time.now - @start_time)
|
69
|
-
sprintf("%s/s", convert_bytes(bytes_per_second))
|
70
|
-
end
|
71
|
-
|
72
|
-
def bytes
|
73
|
-
convert_bytes(@current)
|
74
|
-
end
|
75
|
-
|
76
|
-
def format_time(t)
|
77
|
-
t = t.to_i
|
78
|
-
sec = t % 60
|
79
|
-
min = (t / 60) % 60
|
80
|
-
hour = t / 3600
|
81
|
-
sprintf("%02d:%02d:%02d", hour, min, sec);
|
82
|
-
end
|
83
|
-
|
84
|
-
# ETA stands for Estimated Time of Arrival.
|
85
|
-
def eta
|
86
|
-
if @current == 0
|
87
|
-
"ETA: --:--:--"
|
88
|
-
else
|
89
|
-
elapsed = Time.now - @start_time
|
90
|
-
eta = elapsed * @total / @current - elapsed;
|
91
|
-
sprintf("ETA: %s", format_time(eta))
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
def elapsed
|
96
|
-
elapsed = Time.now - @start_time
|
97
|
-
sprintf("Time: %s", format_time(elapsed))
|
98
|
-
end
|
99
|
-
|
100
|
-
def stat
|
101
|
-
if @is_finished then elapsed else eta end
|
102
|
-
end
|
103
|
-
|
104
|
-
def stat_for_file_transfer
|
105
|
-
if @is_finished then
|
106
|
-
sprintf("%s %s %s", bytes, transfer_rate, elapsed)
|
107
|
-
else
|
108
|
-
sprintf("%s %s %s", bytes, transfer_rate, eta)
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
def eol
|
113
|
-
if @is_finished then "\n" else "\r" end
|
114
|
-
end
|
115
|
-
|
116
|
-
def bar
|
117
|
-
len = percentage * @bar_length / 100
|
118
|
-
sprintf("|%s%s|", @bar_mark * len, " " * (@bar_length - len))
|
119
|
-
end
|
120
|
-
|
121
|
-
def percentage
|
122
|
-
if @total.zero?
|
123
|
-
100
|
124
|
-
else
|
125
|
-
@current * 100 / @total
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
def title
|
130
|
-
@title[0,13] + ":"
|
131
|
-
end
|
132
|
-
|
133
|
-
def get_width
|
134
|
-
# FIXME: I don't know how portable it is.
|
135
|
-
default_width = 80
|
136
|
-
begin
|
137
|
-
tiocgwinsz = 0x5413
|
138
|
-
data = [0, 0, 0, 0].pack("SSSS")
|
139
|
-
if @out.ioctl(tiocgwinsz, data) >= 0 then
|
140
|
-
rows, cols, xpixels, ypixels = data.unpack("SSSS")
|
141
|
-
if cols >= 0 then cols else default_width end
|
142
|
-
else
|
143
|
-
default_width
|
144
|
-
end
|
145
|
-
rescue Exception
|
146
|
-
default_width
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
def show
|
151
|
-
arguments = @format_arguments.map{|method| send(method)}
|
152
|
-
line = sprintf(@format, *arguments)
|
153
|
-
|
154
|
-
width = get_width
|
155
|
-
if line.length == width - 1
|
156
|
-
@out.print(line + eol)
|
157
|
-
elsif line.length >= width
|
158
|
-
@bar_length = [@bar_length - (line.length - width + 1), 0].max
|
159
|
-
if @bar_length == 0 then @out.print(line + eol) else show end
|
160
|
-
else #line.length < width - 1
|
161
|
-
@bar_length += width - line.length + 1
|
162
|
-
show
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
def show_progress
|
167
|
-
if @total.zero?
|
168
|
-
cur_percentage = 100
|
169
|
-
prev_percentage = 0
|
170
|
-
else
|
171
|
-
cur_percentage = (@current * 100 / @total).to_i
|
172
|
-
prev_percentage = (@previous * 100 / @total).to_i
|
173
|
-
end
|
174
|
-
|
175
|
-
if cur_percentage > prev_percentage || @is_finished
|
176
|
-
show
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
public
|
181
|
-
def file_transfer_mode
|
182
|
-
@format_arguments = [:title, :percentage, :bar, :stat_for_file_transfer]
|
183
|
-
end
|
184
|
-
|
185
|
-
def title=(str)
|
186
|
-
@title = str
|
187
|
-
end
|
188
|
-
|
189
|
-
def bar_mark=(mark)
|
190
|
-
@bar_mark = String(mark)[0..0]
|
191
|
-
end
|
192
|
-
|
193
|
-
def total_overflow=(boolv)
|
194
|
-
@total_overflow = boolv ? true : false
|
195
|
-
end
|
196
|
-
|
197
|
-
def format=(format)
|
198
|
-
@format = format
|
199
|
-
end
|
200
|
-
|
201
|
-
def format_arguments=(arguments)
|
202
|
-
@format_arguments = arguments
|
203
|
-
end
|
204
|
-
|
205
|
-
def finish
|
206
|
-
@current = @total
|
207
|
-
@is_finished = true
|
208
|
-
show_progress
|
209
|
-
end
|
210
|
-
|
211
|
-
def flush
|
212
|
-
@out.flush
|
213
|
-
end
|
214
|
-
|
215
|
-
def halt
|
216
|
-
@is_finished = true
|
217
|
-
show_progress
|
218
|
-
end
|
219
|
-
|
220
|
-
def set(count)
|
221
|
-
if count < 0
|
222
|
-
raise "invalid count less than zero: #{count}"
|
223
|
-
elsif count > @total
|
224
|
-
if @total_overflow
|
225
|
-
@total = count + 1
|
226
|
-
else
|
227
|
-
raise "invalid count greater than total: #{count}"
|
228
|
-
end
|
229
|
-
end
|
230
|
-
@current = count
|
231
|
-
show_progress
|
232
|
-
@previous = @current
|
233
|
-
end
|
234
|
-
|
235
|
-
def inc(step = 1)
|
236
|
-
@current += step
|
237
|
-
@current = @total if @current > @total
|
238
|
-
show_progress
|
239
|
-
@previous = @current
|
240
|
-
end
|
241
|
-
|
242
|
-
def inspect
|
243
|
-
"(ProgressBar: #{@current}/#{@total})"
|
244
|
-
end
|
245
|
-
|
246
|
-
end
|
247
|
-
|
248
|
-
|
249
|
-
module Console #:nodoc:
|
250
|
-
# For backward compatibility
|
251
|
-
ProgressBar = ::ProgressBar
|
252
|
-
end
|
253
|
-
|