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.
@@ -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 = if kind_of?(Module)
26
- constant(self.spacename).logger
27
- else
28
- self.class.logger
29
- end
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
- Utilrb.if_ext do
4
- # Check if +klass+ is an ancestor of this class/module
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
- Utilrb.unless_ext do
19
- def has_ancestor?(klass) # :nodoc:
20
- self <= klass || superclass == klass || superclass < klass
21
- end
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
@@ -0,0 +1,11 @@
1
+ class Module
2
+ if Utilrb::RUBY_IS_191 || Utilrb::RUBY_IS_19
3
+ def const_defined_here?(name)
4
+ const_defined?(name, false)
5
+ end
6
+ else
7
+ def const_defined_here?(name)
8
+ const_defined?(name)
9
+ end
10
+ end
11
+ end
@@ -1,26 +1,19 @@
1
+ require 'utilrb/module/const_defined_here_p'
1
2
  class Module
2
- if Utilrb::RUBY_IS_19
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?(name, false)
14
- const_get(name)
15
- else
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
- unless defined? @singleton_class
39
- klass = class << self; self end
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