facets 2.7.0 → 2.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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,140 @@
|
|
1
|
+
#= Matcher
|
2
|
+
#
|
3
|
+
# Matcher derives from Ruby Quiz #103, the DictionaryMatcher quiz.
|
4
|
+
#
|
5
|
+
class Matcher
|
6
|
+
attr_reader :word_count
|
7
|
+
|
8
|
+
#Contains the index matched, and the word matched
|
9
|
+
class MatchData < Struct.new(:index,:match)
|
10
|
+
def inspect
|
11
|
+
"#{match.inspect}@#{index}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def inspect
|
16
|
+
to_s
|
17
|
+
end
|
18
|
+
|
19
|
+
#Create a DictionaryMatcher with no words in it
|
20
|
+
def initialize
|
21
|
+
@trie = {}
|
22
|
+
@word_count = 0
|
23
|
+
end
|
24
|
+
|
25
|
+
#Add a word to the DictionaryMatcher
|
26
|
+
def add(word)
|
27
|
+
@word_count += 1
|
28
|
+
container = @trie
|
29
|
+
containers=[]
|
30
|
+
|
31
|
+
i=0
|
32
|
+
word.each_byte do |b|
|
33
|
+
container[b] = {} unless container.has_key? b
|
34
|
+
container[:depth]=i
|
35
|
+
containers << container
|
36
|
+
container = container[b]
|
37
|
+
i+=1
|
38
|
+
end
|
39
|
+
containers << container
|
40
|
+
|
41
|
+
container[0] = true # Mark end of word
|
42
|
+
container[:depth]=i
|
43
|
+
|
44
|
+
ff=compute_failure_function word
|
45
|
+
ff.zip(containers).each do |pointto,container|
|
46
|
+
container[:failure]=containers[pointto] if pointto
|
47
|
+
end
|
48
|
+
|
49
|
+
self
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
alias << add
|
54
|
+
|
55
|
+
def compute_failure_function p
|
56
|
+
m=p.size
|
57
|
+
pi=[nil,0]
|
58
|
+
k=0
|
59
|
+
2.upto m do |q|
|
60
|
+
k=pi[k] while k>0 and p[k] != p[q-1]
|
61
|
+
k=k+1 if p[k]==p[q-1]
|
62
|
+
pi[q]=k
|
63
|
+
end
|
64
|
+
pi
|
65
|
+
end
|
66
|
+
private :compute_failure_function
|
67
|
+
|
68
|
+
#Determine whether +string+ was previously <tt>add</tt>ed to the
|
69
|
+
#Trie.
|
70
|
+
def include?(word)
|
71
|
+
container = @trie
|
72
|
+
word.each_byte do |b|
|
73
|
+
break unless container.has_key? b
|
74
|
+
container = container[b]
|
75
|
+
end
|
76
|
+
container[0]
|
77
|
+
end
|
78
|
+
|
79
|
+
#Determines whether one of the words in the DictionaryMatcher is a
|
80
|
+
#substring of
|
81
|
+
#+string+. Returns the index of the match if found, +nil+ if not
|
82
|
+
#found.
|
83
|
+
def =~ text
|
84
|
+
internal_match(text){|md| return md.index}
|
85
|
+
nil
|
86
|
+
end
|
87
|
+
|
88
|
+
#Determine whether one of the words in the DictionaryMatcher is a
|
89
|
+
#substring of
|
90
|
+
#+string+. Returns a DictionaryMatcher::MatchData object if found,
|
91
|
+
#+nil+ if not #found.
|
92
|
+
def match text
|
93
|
+
internal_match(text){|md| return md}
|
94
|
+
nil
|
95
|
+
end
|
96
|
+
|
97
|
+
def internal_match string
|
98
|
+
node=@trie
|
99
|
+
pos=0
|
100
|
+
string.each_byte do |b|
|
101
|
+
advance=false
|
102
|
+
until advance
|
103
|
+
nextnode=node[b]
|
104
|
+
if not nextnode
|
105
|
+
if node[:failure]
|
106
|
+
node=node[:failure]
|
107
|
+
else
|
108
|
+
advance=true
|
109
|
+
end
|
110
|
+
elsif nextnode[0]
|
111
|
+
yield MatchData.new(pos, string[pos+1-nextnode[:depth],nextnode[:depth]])
|
112
|
+
advance=true
|
113
|
+
node=@trie
|
114
|
+
else
|
115
|
+
advance=true
|
116
|
+
node=nextnode
|
117
|
+
end
|
118
|
+
pos+=1
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
private :internal_match
|
123
|
+
|
124
|
+
#Scans +string+ for all occurrances of strings in the
|
125
|
+
#DictionaryMatcher.
|
126
|
+
#Overlapping matches are skipped (only the first one is yielded), and
|
127
|
+
#when some strings in the
|
128
|
+
#DictionaryMatcher are substrings of others, only the shortest match
|
129
|
+
#at a given position is found.
|
130
|
+
def scan(text, &block)
|
131
|
+
matches=[]
|
132
|
+
block= lambda{ |md| matches << md } unless block
|
133
|
+
internal_match(text,&block)
|
134
|
+
matches
|
135
|
+
end
|
136
|
+
|
137
|
+
#Case equality. Similar to =~.
|
138
|
+
alias_method :===, :=~
|
139
|
+
end
|
140
|
+
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# Memoizer
|
2
|
+
#
|
3
|
+
# Copyright (c) 2006 Erik Veenstra
|
4
|
+
#
|
5
|
+
# See http://javathink.blogspot.com/2008/09/what-is-memoizer-and-why-should-you.html
|
6
|
+
|
7
|
+
# Memoizer wraps objects to provide cached method calls.
|
8
|
+
#
|
9
|
+
# class X
|
10
|
+
# def initialize ; @tick = 0 ; end
|
11
|
+
# def tick; @tick + 1; end
|
12
|
+
# def memo; @memo ||= Memoizer.new(self) ; end
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# x = X.new
|
16
|
+
# x.tick #=> 1
|
17
|
+
# x.memo.tick #=> 2
|
18
|
+
# x.tick #=> 3
|
19
|
+
# x.memo.tick #=> 2
|
20
|
+
# x.tick #=> 4
|
21
|
+
# x.memo.tick #=> 2
|
22
|
+
#
|
23
|
+
# You can also use to cache collections of objects to gain code speed ups.
|
24
|
+
#
|
25
|
+
# points = points.collect{|point| Memoizer.cache(point)}
|
26
|
+
#
|
27
|
+
# After our algorithm has finished using points, we want to get rid of
|
28
|
+
# these Memoizer objects. That's easy:
|
29
|
+
#
|
30
|
+
# points = points.collect{|point| point.__self__ }
|
31
|
+
#
|
32
|
+
# Or if you prefer (it is ever so slightly safer):
|
33
|
+
#
|
34
|
+
# points = points.collect{|point| Memoizer.uncache(point)}
|
35
|
+
#
|
36
|
+
class Memoizer
|
37
|
+
|
38
|
+
#private :class, :clone, :display, :type, :method, :to_a, :to_s
|
39
|
+
private *instance_methods(true).select{ |m| m.to_s !~ /^__/ }
|
40
|
+
|
41
|
+
def initialize(object)
|
42
|
+
@self = object
|
43
|
+
@cache = {}
|
44
|
+
end
|
45
|
+
|
46
|
+
def __self__ ; @self ; end
|
47
|
+
|
48
|
+
# Not thread-safe! Speed is important in caches... ;]
|
49
|
+
def method_missing(method_name, *args, &block)
|
50
|
+
@cache[[method_name, args, block]] ||= @self.__send__(method_name, *args, &block)
|
51
|
+
end
|
52
|
+
|
53
|
+
#def self; @self; end
|
54
|
+
|
55
|
+
def self.cache(object)
|
56
|
+
new(object)
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.uncache(cached_object)
|
60
|
+
cached_object.instance_variable_get('@self')
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
@@ -70,11 +70,16 @@ class Module
|
|
70
70
|
methods = {}
|
71
71
|
mod.instance_methods(false).each do |m|
|
72
72
|
methods[m.to_sym] = mod.instance_method(m)
|
73
|
-
mod.
|
74
|
-
|
75
|
-
super
|
73
|
+
mod.module_eval %{
|
74
|
+
def #{m}(*a,&b)
|
75
|
+
super(*a,&b)
|
76
76
|
end
|
77
|
-
|
77
|
+
}
|
78
|
+
#mod.instance_eval do
|
79
|
+
#define_method(m)
|
80
|
+
# super
|
81
|
+
#end
|
82
|
+
#end
|
78
83
|
end
|
79
84
|
|
80
85
|
# Add a method for the namespace that delegates
|
@@ -1,122 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
# Normally when including modules, class/module methods are not
|
4
|
-
# extended. To achieve this behavior requires some clever
|
5
|
-
# Ruby Karate. Instead class_extension provides an easy to use
|
6
|
-
# and clean solution. Simply place the extending class methods
|
7
|
-
# in a block of the special module method #class_extension.
|
8
|
-
#
|
9
|
-
# module Mix
|
10
|
-
# def inst_meth
|
11
|
-
# puts 'inst_meth'
|
12
|
-
# end
|
13
|
-
#
|
14
|
-
# class_extend do
|
15
|
-
# def class_meth
|
16
|
-
# "Class Method!"
|
17
|
-
# end
|
18
|
-
# end
|
19
|
-
# end
|
20
|
-
#
|
21
|
-
# class X
|
22
|
-
# include Mix
|
23
|
-
# end
|
24
|
-
#
|
25
|
-
# X.class_meth #=> "Class Method!"
|
26
|
-
#
|
27
|
-
# == History
|
28
|
-
#
|
29
|
-
# Thanks to Trans, Nobu and Ulysses for their original on this concept.
|
30
|
-
#
|
31
|
-
# == Authors
|
32
|
-
#
|
33
|
-
# * Daniel Schierbeck
|
34
|
-
# * Thomas Sawyer
|
35
|
-
# * Nobu Nakada
|
36
|
-
# * Ulysses
|
37
|
-
#
|
38
|
-
# == Copying
|
39
|
-
#
|
40
|
-
# Copyright (c) 2006 Daniel Schierbeck
|
41
|
-
#
|
42
|
-
# Ruby License
|
43
|
-
#
|
44
|
-
# This module is free software. You may use, modify, and/or redistribute this
|
45
|
-
# software under the same terms as Ruby.
|
46
|
-
#
|
47
|
-
# This program is distributed in the hope that it will be useful, but WITHOUT
|
48
|
-
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
49
|
-
# FOR A PARTICULAR PURPOSE.
|
50
|
-
|
51
|
-
#
|
52
|
-
class Module
|
53
|
-
|
54
|
-
alias_method :append_features_without_class_extension, :append_features
|
55
|
-
|
56
|
-
# Normally when including modules, class/module methods are not
|
57
|
-
# extended. To achieve this behavior requires some clever
|
58
|
-
# Ruby Karate. Instead class_extension provides an easy to use
|
59
|
-
# and clean solution. Simply place the extending class methods
|
60
|
-
# in a block of the special module method #class_extension.
|
61
|
-
#
|
62
|
-
# module Mix
|
63
|
-
# def inst_meth
|
64
|
-
# puts 'inst_meth'
|
65
|
-
# end
|
66
|
-
#
|
67
|
-
# class_extend do
|
68
|
-
# def class_meth
|
69
|
-
# "Class Method!"
|
70
|
-
# end
|
71
|
-
# end
|
72
|
-
# end
|
73
|
-
#
|
74
|
-
# class X
|
75
|
-
# include Mix
|
76
|
-
# end
|
77
|
-
#
|
78
|
-
# X.class_meth #=> "Class Method!"
|
79
|
-
#
|
80
|
-
# NOTE: This old #class_extension version of this method
|
81
|
-
# did not extend the containing class automatically --it had
|
82
|
-
# to be done by hand. With #class_extend, that is no longer
|
83
|
-
# the case.
|
84
|
-
#
|
85
|
-
def class_extend(*mods, &block)
|
86
|
-
@class_extension ||= Module.new do
|
87
|
-
def self.append_features(mod)
|
88
|
-
append_features_without_class_extension(mod)
|
89
|
-
end
|
90
|
-
end
|
91
|
-
@class_extension.__send__(:include, *mods)
|
92
|
-
@class_extension.module_eval(&block) if block_given?
|
93
|
-
extend(@class_extension) # extend this module too
|
94
|
-
@class_extension
|
95
|
-
end
|
96
|
-
|
97
|
-
# TODO: DEPRECATE
|
98
|
-
alias_method :class_extension, :class_extend
|
99
|
-
|
100
|
-
#private :class_extend
|
101
|
-
|
102
|
-
# Override +append_features+ to handle class-inheritable extensions.
|
103
|
-
def append_features(mod)
|
104
|
-
append_features_without_class_extension(mod)
|
105
|
-
mod.extend(class_extend)
|
106
|
-
if mod.instance_of? Module
|
107
|
-
mod.__send__(:class_extend).__send__(:include, class_extend)
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
end
|
112
|
-
|
113
|
-
class Class
|
114
|
-
# For Class, #class_extend is the same as class_eval.
|
115
|
-
# The alternative is to "undef_method :class_extend",
|
116
|
-
# but this seems uneccessarily limited.
|
117
|
-
#
|
118
|
-
def class_extend(&blk)
|
119
|
-
class_eval(&blk)
|
120
|
-
end
|
121
|
-
end
|
1
|
+
warn "use 'facets/class_extend' for future versions"
|
2
|
+
require 'facets/class_extend'
|
122
3
|
|
data/lib/more/facets/ostruct.rb
CHANGED
@@ -34,13 +34,13 @@ class OpenStruct
|
|
34
34
|
# o.name = 'John Smith'
|
35
35
|
# o.gender = :M
|
36
36
|
# o.age = 71
|
37
|
-
# end
|
37
|
+
# end
|
38
38
|
#
|
39
39
|
# You can still provide a hash for initialization purposes, and even combine
|
40
40
|
# the two approaches if you wish.
|
41
41
|
#
|
42
42
|
# person = OpenStruct.new(:name => 'John Smith', :age => 31) do |p|
|
43
|
-
# p.gender = :M
|
43
|
+
# p.gender = :M
|
44
44
|
# end
|
45
45
|
#
|
46
46
|
# Alternatively you can provide a default block:
|
@@ -201,13 +201,6 @@ class Hash
|
|
201
201
|
OpenStruct.new(self)
|
202
202
|
end
|
203
203
|
|
204
|
-
# CREDIT Alison Rowland, Jamie Macey, Mat Schaffer
|
205
|
-
|
206
|
-
#--
|
207
|
-
# Special thanks to Alison Rowland, Jamie Macey and Mat Schaffer
|
208
|
-
# for inspiring recursive improvements.
|
209
|
-
#++
|
210
|
-
|
211
204
|
# Like to_ostruct but recusively objectifies all hash elements as well.
|
212
205
|
#
|
213
206
|
# o = { 'a' => { 'b' => 1 } }.to_ostruct_recurse
|
@@ -223,6 +216,8 @@ class Hash
|
|
223
216
|
# o = h.to_ostruct_recurse( { h['a'] => h['a'] } )
|
224
217
|
# o.a['b'] #=> 1
|
225
218
|
#
|
219
|
+
# CREDIT: Alison Rowland, Jamie Macey, Mat Schaffer
|
220
|
+
|
226
221
|
def to_ostruct_recurse(exclude={})
|
227
222
|
return exclude[self] if exclude.key?( self )
|
228
223
|
o = exclude[self] = OpenStruct.new
|
@@ -233,5 +228,10 @@ class Hash
|
|
233
228
|
o.__update__(h)
|
234
229
|
end
|
235
230
|
|
231
|
+
#--
|
232
|
+
# Special thanks to Alison Rowland, Jamie Macey and Mat Schaffer
|
233
|
+
# for inspiring recursive improvements.
|
234
|
+
#++
|
235
|
+
|
236
236
|
end
|
237
237
|
|
data/lib/more/facets/pathlist.rb
CHANGED
@@ -89,16 +89,8 @@ $:.find_ext = 'rb'
|
|
89
89
|
# Doesn't work
|
90
90
|
#ENV['PATH'] = PathList.new(ENV['PATH'])
|
91
91
|
|
92
|
-
#++
|
93
92
|
|
94
|
-
|
95
|
-
# _____ _
|
96
|
-
# |_ _|__ ___| |_
|
97
|
-
# | |/ _ \/ __| __|
|
98
|
-
# | | __/\__ \ |_
|
99
|
-
# |_|\___||___/\__|
|
100
|
-
#
|
101
|
-
=begin #testing
|
93
|
+
=begin test
|
102
94
|
|
103
95
|
require 'test/unit'
|
104
96
|
|
data/lib/more/facets/pathname.rb
CHANGED
@@ -129,7 +129,7 @@ class Pathname
|
|
129
129
|
flags = 0
|
130
130
|
opts.each do |opt|
|
131
131
|
case opt when Symbol, String
|
132
|
-
flags += File.const_get("FNM_#{opt}".upcase)
|
132
|
+
flags += ::File.const_get("FNM_#{opt}".upcase)
|
133
133
|
else
|
134
134
|
flags += opt
|
135
135
|
end
|
@@ -156,10 +156,17 @@ class Pathname
|
|
156
156
|
Dir.glob(::File.join(self.to_s, '*')).empty?
|
157
157
|
end
|
158
158
|
|
159
|
-
|
159
|
+
#
|
160
|
+
def uptodate?(*sources)
|
161
|
+
::FileUtils.uptodate?(to_s, sources.flatten)
|
162
|
+
end
|
160
163
|
|
161
|
-
#
|
162
|
-
|
164
|
+
#
|
165
|
+
def outofdate?(*sources)
|
166
|
+
::FileUtils.outofdate?(to_s, sources.flatten)
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
163
170
|
|
164
171
|
class NilClass
|
165
172
|
# Provide platform dependent null path.
|