utilrb 1.3.3 → 1.4.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.txt +17 -0
- data/Manifest.txt +11 -0
- data/README.txt +9 -5
- data/Rakefile +30 -50
- data/ext/extconf.rb +14 -1
- data/ext/value_set.cc +43 -1
- data/lib/utilrb/array/to_s.rb +1 -0
- data/lib/utilrb/common.rb +3 -2
- data/lib/utilrb/configsearch/configuration_finder.rb +78 -0
- data/lib/utilrb/configsearch.rb +2 -0
- data/lib/utilrb/hash/recursive_merge.rb +26 -0
- data/lib/utilrb/hash/to_s.rb +1 -0
- data/lib/utilrb/kernel/load_dsl_file.rb +187 -0
- data/lib/utilrb/kernel/options.rb +10 -1
- data/lib/utilrb/kernel/with_module.rb +53 -0
- data/lib/utilrb/logger/hierarchy.rb +21 -5
- data/lib/utilrb/logger/io.rb +25 -0
- data/lib/utilrb/marshal/load_with_missing_constants.rb +63 -0
- data/lib/utilrb/module/ancestor_p.rb +12 -18
- data/lib/utilrb/module/cached_enum.rb +15 -0
- data/lib/utilrb/module/const_defined_here_p.rb +11 -0
- data/lib/utilrb/module/define_or_reuse.rb +15 -22
- data/lib/utilrb/module/include.rb +12 -0
- data/lib/utilrb/module/inherited_enumerable.rb +15 -0
- data/lib/utilrb/object/scoped_eval.rb +17 -0
- data/lib/utilrb/object/singleton_class.rb +3 -44
- data/lib/utilrb/pkgconfig.rb +311 -27
- data/lib/utilrb/symbol/to_str.rb +5 -0
- data/lib/utilrb/value_set.rb +12 -0
- data/test/data/test_pkgconfig_empty.pc +10 -0
- data/test/test_kernel.rb +158 -0
- data/test/test_module.rb +11 -10
- data/test/test_object.rb +0 -28
- data/test/test_pkgconfig.rb +35 -1
- metadata +88 -44
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'utilrb/common'
|
2
|
+
module Kernel
|
3
|
+
if Utilrb::RUBY_IS_191
|
4
|
+
def with_module(*consts, &blk)
|
5
|
+
slf = self
|
6
|
+
|
7
|
+
l = if !block_given? && consts.last.respond_to?(:to_str)
|
8
|
+
eval_string = consts.pop
|
9
|
+
lambda { slf.instance_eval(eval_string) }
|
10
|
+
else
|
11
|
+
lambda { slf.instance_eval(&blk) }
|
12
|
+
end
|
13
|
+
|
14
|
+
consts.inject(l) {|l, k| lambda { k.class_eval(&l) } }.call
|
15
|
+
end
|
16
|
+
else
|
17
|
+
module WithModuleConstResolutionExtension
|
18
|
+
def const_missing(const_name)
|
19
|
+
if with_module_setup = Thread.current[:__with_module__]
|
20
|
+
if consts = with_module_setup.last
|
21
|
+
consts.each do |mod|
|
22
|
+
if mod.const_defined?(const_name)
|
23
|
+
return mod.const_get(const_name)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
super
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def with_module(*consts, &block)
|
33
|
+
Thread.current[:__with_module__] ||= Array.new
|
34
|
+
Thread.current[:__with_module__].push consts
|
35
|
+
Kernel.send(:extend, WithModuleConstResolutionExtension)
|
36
|
+
Object.extend WithModuleConstResolutionExtension
|
37
|
+
|
38
|
+
eval_string =
|
39
|
+
if !block_given? && consts.last.respond_to?(:to_str)
|
40
|
+
consts.pop
|
41
|
+
end
|
42
|
+
if eval_string
|
43
|
+
instance_eval(eval_string)
|
44
|
+
else
|
45
|
+
instance_eval(&block)
|
46
|
+
end
|
47
|
+
|
48
|
+
ensure
|
49
|
+
Thread.current[:__with_module__].pop
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
@@ -20,13 +20,29 @@ class Logger
|
|
20
20
|
# be returned.
|
21
21
|
module Hierarchy
|
22
22
|
attr_writer :logger
|
23
|
+
|
24
|
+
def has_own_logger?
|
25
|
+
defined?(@logger) && @logger
|
26
|
+
end
|
27
|
+
|
28
|
+
def make_own_logger(new_level = nil)
|
29
|
+
if !has_own_logger?
|
30
|
+
@logger = self.logger.dup
|
31
|
+
end
|
32
|
+
if new_level
|
33
|
+
@logger.level = new_level
|
34
|
+
end
|
35
|
+
@logger
|
36
|
+
end
|
37
|
+
|
23
38
|
def logger
|
24
39
|
return @logger if defined?(@logger) && @logger
|
25
|
-
@logger =
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
40
|
+
@logger =
|
41
|
+
if kind_of?(Module)
|
42
|
+
constant(self.spacename).logger
|
43
|
+
else
|
44
|
+
self.class.logger
|
45
|
+
end
|
30
46
|
end
|
31
47
|
end
|
32
48
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class Logger
|
2
|
+
# An IO-like interface for a logger object
|
3
|
+
class LoggerIO
|
4
|
+
attr_reader :logger
|
5
|
+
attr_reader :level
|
6
|
+
|
7
|
+
def initialize(logger, level)
|
8
|
+
@logger, @level = logger, level
|
9
|
+
@buffer = ''
|
10
|
+
end
|
11
|
+
def puts(msg)
|
12
|
+
print msg
|
13
|
+
logger.send(level, @buffer)
|
14
|
+
@buffer = ''
|
15
|
+
end
|
16
|
+
def print(msg)
|
17
|
+
@buffer << msg
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def io(level)
|
22
|
+
LoggerIO.new(self, level)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Marshal
|
2
|
+
if defined? BasicObject
|
3
|
+
class BlackHole < BasicObject
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
class BlackHole
|
8
|
+
class << self
|
9
|
+
:name
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(*args)
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :__content__
|
16
|
+
def method_missing(*args)
|
17
|
+
end
|
18
|
+
def self._load(*args)
|
19
|
+
hole = BlackHole.new
|
20
|
+
hole.instance_variable_set(:@__content__, args)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.method_missing(*args)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.load_with_missing_constants(str_or_io)
|
28
|
+
if str_or_io.respond_to?(:tell)
|
29
|
+
original_pos = str_or_io.tell
|
30
|
+
end
|
31
|
+
|
32
|
+
self.load(str_or_io)
|
33
|
+
rescue Exception => e
|
34
|
+
case e.message
|
35
|
+
when /undefined class\/module ((?:\w+::)+)$/
|
36
|
+
names = $1.split('::')
|
37
|
+
missing = names.pop
|
38
|
+
base = names.inject(Object) { |m, n| m.const_get(n) }
|
39
|
+
base.const_set(missing, Module.new)
|
40
|
+
|
41
|
+
if original_pos
|
42
|
+
str_or_io.seek(original_pos)
|
43
|
+
end
|
44
|
+
retry
|
45
|
+
when /undefined class\/module ((?:\w+::)+)(\w+)$/
|
46
|
+
mod, klass = $1, $2
|
47
|
+
full_name = "#{mod}#{klass}"
|
48
|
+
mod = mod.split('::').inject(Object) { |m, n| m.const_get(n) }
|
49
|
+
|
50
|
+
blackhole = Class.new(BlackHole) do
|
51
|
+
@name = full_name
|
52
|
+
end
|
53
|
+
mod.const_set(klass, blackhole)
|
54
|
+
|
55
|
+
if original_pos
|
56
|
+
str_or_io.seek(original_pos)
|
57
|
+
end
|
58
|
+
retry
|
59
|
+
end
|
60
|
+
raise
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
@@ -1,24 +1,18 @@
|
|
1
1
|
require 'utilrb/common'
|
2
2
|
class Module
|
3
|
-
|
4
|
-
|
5
|
-
#
|
6
|
-
# It works for singleton classes as well:
|
7
|
-
#
|
8
|
-
# class MyClass; end
|
9
|
-
# obj = MyClass.new
|
10
|
-
# singleton = class << obj; obj end
|
11
|
-
#
|
12
|
-
# singleton.has_ancestor?(MyClass) # => true
|
13
|
-
#
|
14
|
-
def has_ancestor?(klass)
|
15
|
-
self <= klass || (is_singleton? && superclass.has_ancestor?(klass))
|
16
|
-
end
|
3
|
+
def has_ancestor?(klass) # :nodoc:
|
4
|
+
self <= klass
|
17
5
|
end
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
6
|
+
end
|
7
|
+
class Class
|
8
|
+
def has_ancestor?(klass) # :nodoc:
|
9
|
+
# We first test
|
10
|
+
# self <= class
|
11
|
+
# as self.superclass goes to the next *CLASS* in the chain, i.e. skips
|
12
|
+
# included modules
|
13
|
+
#
|
14
|
+
# Then, the superclass test is used in case +self+ is a singleton
|
15
|
+
self <= klass || (superclass <= klass)
|
22
16
|
end
|
23
17
|
end
|
24
18
|
|
@@ -1,3 +1,15 @@
|
|
1
|
+
require 'utilrb/object/attribute'
|
2
|
+
module CachedValuesSupport
|
3
|
+
attribute(:cached_variables) { Set.new }
|
4
|
+
def initialize_copy(other)
|
5
|
+
super
|
6
|
+
|
7
|
+
cached_variables.each do |varname|
|
8
|
+
instance_variable_set(varname, nil)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
1
13
|
class Module
|
2
14
|
# Creates <tt>enum_#{name}</tt> method which returs an Enumerator object
|
3
15
|
# for the <tt>each_#{enum_name}</tt> method. This enumerator is created
|
@@ -7,16 +19,19 @@ class Module
|
|
7
19
|
# one argument, which is given in argument of the 'enum' method. In that
|
8
20
|
# case, an enumerator is created for each argument
|
9
21
|
def cached_enum(enum_name, name, with_arg)
|
22
|
+
include CachedValuesSupport
|
10
23
|
if with_arg
|
11
24
|
class_eval <<-EOD
|
12
25
|
def enum_#{name}(arg)
|
13
26
|
@enum_#{name} ||= Hash.new
|
27
|
+
cached_variables << :@enum_#{name}
|
14
28
|
@enum_#{name}[arg] ||= enum_for(:each_#{enum_name}, arg)
|
15
29
|
end
|
16
30
|
EOD
|
17
31
|
else
|
18
32
|
class_eval <<-EOD
|
19
33
|
def enum_#{name}
|
34
|
+
cached_variables << :@enum_#{name}
|
20
35
|
@enum_#{name} ||= enum_for(:each_#{enum_name})
|
21
36
|
end
|
22
37
|
EOD
|
@@ -1,26 +1,19 @@
|
|
1
|
+
require 'utilrb/module/const_defined_here_p'
|
1
2
|
class Module
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
const_set(name, (value || yield))
|
17
|
-
end
|
18
|
-
end
|
19
|
-
else
|
20
|
-
def define_or_reuse(name, value = nil)
|
21
|
-
if const_defined?(name)
|
22
|
-
const_get(name)
|
23
|
-
else
|
3
|
+
# :call-seq
|
4
|
+
# define_or_reuse(name, value) -> value
|
5
|
+
# define_or_reuse(name) { ... } -> value
|
6
|
+
#
|
7
|
+
# Defines a new constant under a given module, or reuse the
|
8
|
+
# already-existing value if the constant is already defined.
|
9
|
+
#
|
10
|
+
# In the first form, the method gets its value from its argument.
|
11
|
+
# In the second case, it calls the provided block
|
12
|
+
def define_or_reuse(name, value = nil)
|
13
|
+
if const_defined_here?(name)
|
14
|
+
const_get(name)
|
15
|
+
else
|
16
|
+
module_eval do
|
24
17
|
const_set(name, (value || yield))
|
25
18
|
end
|
26
19
|
end
|
@@ -14,6 +14,18 @@ class Module
|
|
14
14
|
# * if it is included in a Class, the ClassExtension module
|
15
15
|
# extends the class.
|
16
16
|
def include(mod)
|
17
|
+
if mod.const_defined?(:ModuleExtension)
|
18
|
+
if is_a?(Module)
|
19
|
+
unless const_defined?(:ModuleExtension)
|
20
|
+
const_set(:ModuleExtension, Module.new)
|
21
|
+
end
|
22
|
+
const_get(:ModuleExtension).class_eval do
|
23
|
+
__instance_include__ mod.const_get(:ModuleExtension)
|
24
|
+
end
|
25
|
+
extend mod.const_get(:ModuleExtension)
|
26
|
+
end
|
27
|
+
# Do nothing on classes
|
28
|
+
end
|
17
29
|
if mod.const_defined?(:ClassExtension)
|
18
30
|
if !is_a?(Class)
|
19
31
|
unless const_defined?(:ClassExtension)
|
@@ -11,6 +11,11 @@ class Module
|
|
11
11
|
|
12
12
|
options[:enum_with] ||= :each
|
13
13
|
|
14
|
+
class_eval <<-EOF
|
15
|
+
def all_#{name}; each_#{name}.to_a end
|
16
|
+
def self_#{name}; @#{attribute_name} end
|
17
|
+
EOF
|
18
|
+
|
14
19
|
if options[:map]
|
15
20
|
class_eval <<-EOF
|
16
21
|
def each_#{name}(key = nil, uniq = true)
|
@@ -49,6 +54,12 @@ class Module
|
|
49
54
|
end
|
50
55
|
self
|
51
56
|
end
|
57
|
+
def find_#{name}(key)
|
58
|
+
each_#{name}(key, true) do |value|
|
59
|
+
return value
|
60
|
+
end
|
61
|
+
nil
|
62
|
+
end
|
52
63
|
def has_#{name}?(key)
|
53
64
|
for klass in ancestors
|
54
65
|
if klass.instance_variable_defined?(:@#{attribute_name})
|
@@ -61,6 +72,10 @@ class Module
|
|
61
72
|
else
|
62
73
|
class_eval <<-EOF
|
63
74
|
def each_#{name}
|
75
|
+
if !block_given?
|
76
|
+
return enum_for(:each_#{name})
|
77
|
+
end
|
78
|
+
|
64
79
|
for klass in ancestors
|
65
80
|
if klass.instance_variable_defined?(:@#{attribute_name})
|
66
81
|
klass.#{attribute_name}.#{options[:enum_with]} { |el| yield(el) }
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'utilrb/common'
|
2
|
+
require 'utilrb/kernel/with_module'
|
3
|
+
class Object
|
4
|
+
if Utilrb::RUBY_IS_191
|
5
|
+
def scoped_eval(type = :instance_eval, &b)
|
6
|
+
modules = b.binding.eval "Module.nesting"
|
7
|
+
with_module(*modules) do
|
8
|
+
send(type, &b)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
else
|
12
|
+
def scoped_eval(type = :instance_eval, &b)
|
13
|
+
send(type, &b)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
@@ -1,30 +1,8 @@
|
|
1
1
|
require 'utilrb/common'
|
2
2
|
require 'utilrb/object/address'
|
3
3
|
|
4
|
-
class Class
|
5
|
-
unless method_defined?(:__ancestors__)
|
6
|
-
alias __ancestors__ ancestors
|
7
|
-
end
|
8
|
-
|
9
|
-
attr_reader :singleton_instance
|
10
|
-
|
11
|
-
Utilrb.require_ext("Object#ancestors") do
|
12
|
-
def ancestors
|
13
|
-
if is_singleton?
|
14
|
-
__ancestors__.unshift(self)
|
15
|
-
else
|
16
|
-
__ancestors__
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
class Object
|
23
|
-
# Returns true if this object has its own singleton class
|
24
|
-
def has_singleton?; defined? @singleton_class end
|
25
|
-
end
|
26
|
-
|
27
4
|
class Object
|
5
|
+
if !Object.new.respond_to?(:singleton_class)
|
28
6
|
# Returns the singleton class for this object.
|
29
7
|
#
|
30
8
|
# In Ruby 1.8, makes sure that the #superclass method of the singleton class
|
@@ -35,27 +13,8 @@ class Object
|
|
35
13
|
# defined, which returns the object instance the class is the singleton
|
36
14
|
# of.
|
37
15
|
def singleton_class
|
38
|
-
|
39
|
-
|
40
|
-
klass.instance_variable_set(:@singleton_instance, self)
|
41
|
-
@singleton_class = klass
|
42
|
-
|
43
|
-
unless Utilrb::RUBY_IS_19
|
44
|
-
instance = self
|
45
|
-
klass.class_eval do
|
46
|
-
@superclass = instance.class
|
47
|
-
class << self
|
48
|
-
attr_reader :superclass
|
49
|
-
def name
|
50
|
-
"#{superclass.name}!0x#{@singleton_instance.address.to_s(16)}"
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
klass
|
56
|
-
end
|
57
|
-
|
58
|
-
@singleton_class
|
16
|
+
class << self; self end
|
17
|
+
end
|
59
18
|
end
|
60
19
|
end
|
61
20
|
|