/usr/lib/ruby/vendor_ruby/naught/null_class_builder.rb is in ruby-naught 1.0.0-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | require 'naught/basic_object'
require 'naught/conversions'
module Naught
class NullClassBuilder
# make sure this module exists
module Commands
end
attr_accessor :base_class, :inspect_proc, :interface_defined
def initialize
@interface_defined = false
@base_class = Naught::BasicObject
@inspect_proc = lambda { '<null>' }
@stub_strategy = :stub_method_returning_nil
define_basic_methods
end
def interface_defined?
!!@interface_defined
end
def customize(&customization_block)
return unless customization_block
customization_module.module_exec(self, &customization_block)
end
def customization_module
@customization_module ||= Module.new
end
def null_equivalents
@null_equivalents ||= [nil]
end
def generate_class
respond_to_any_message unless interface_defined?
generation_mod = Module.new
customization_mod = customization_module # get a local binding
builder = self
apply_operations(operations, generation_mod)
null_class = Class.new(@base_class) do
const_set :GeneratedMethods, generation_mod
const_set :Customizations, customization_mod
const_set :NULL_EQUIVS, builder.null_equivalents
include Conversions
remove_const :NULL_EQUIVS
Conversions.instance_methods.each do |instance_method|
undef_method(instance_method)
end
const_set :Conversions, Conversions
include NullObjectTag
include generation_mod
include customization_mod
end
apply_operations(class_operations, null_class)
null_class
end
def method_missing(method_name, *args, &block)
command_name = command_name_for_method(method_name)
if Commands.const_defined?(command_name)
command_class = Commands.const_get(command_name)
command_class.new(self, *args, &block).call
else
super
end
end
if RUBY_VERSION >= '1.9'
def respond_to_missing?(method_name, include_private = false)
command_name = command_name_for_method(method_name)
Commands.const_defined?(command_name) || super
rescue NameError
super
end
else
def respond_to?(method_name, include_private = false)
command_name = command_name_for_method(method_name)
Commands.const_defined?(command_name) || super
rescue NameError
super
end
end
############################################################################
# Builder API
#
# See also the contents of lib/naught/null_class_builder/commands
############################################################################
def black_hole
@stub_strategy = :stub_method_returning_self
end
def respond_to_any_message
defer(:prepend => true) do |subject|
subject.module_eval do
def respond_to?(*)
true
end
end
stub_method(subject, :method_missing)
end
@interface_defined = true
end
def defer(options = {}, &deferred_operation)
list = options[:class] ? class_operations : operations
if options[:prepend]
list.unshift(deferred_operation)
else
list << deferred_operation
end
end
def stub_method(subject, name)
send(@stub_strategy, subject, name)
end
private
def define_basic_methods
define_basic_instance_methods
define_basic_class_methods
end
def apply_operations(operations, module_or_class)
operations.each do |operation|
operation.call(module_or_class)
end
end
def define_basic_instance_methods
defer do |subject|
subject.module_exec(@inspect_proc) do |inspect_proc|
define_method(:inspect, &inspect_proc)
def initialize(*)
end
end
end
end
def define_basic_class_methods
defer(:class => true) do |subject|
subject.module_eval do
class << self
alias_method :get, :new
end
klass = self
define_method(:class) { klass }
end
end
end
def class_operations
@class_operations ||= []
end
def operations
@operations ||= []
end
def stub_method_returning_nil(subject, name)
subject.module_eval do
define_method(name) { |*| nil }
end
end
def stub_method_returning_self(subject, name)
subject.module_eval do
define_method(name) { |*| self }
end
end
def command_name_for_method(method_name)
method_name.to_s.gsub(/(?:^|_)([a-z])/) { Regexp.last_match[1].upcase }
end
end
end
|