Module: Kernel
- Defined in:
- lib/utilrb/kernel/poll.rb,
lib/utilrb/kernel/arity.rb,
lib/utilrb/kernel/options.rb,
lib/utilrb/kernel/require.rb,
lib/utilrb/enumerable/null.rb,
lib/utilrb/kernel/with_module.rb,
lib/utilrb/kernel/load_dsl_file.rb
Defined Under Namespace
Modules: WithModuleConstResolutionExtension
Class Method Summary collapse
Instance Method Summary collapse
-
#check_arity(object, arity, strict: nil) ⇒ Object
Raises if
object
can accept calls with exactlyarity
arguments. - #dsl_exec(proxied_object, context, full_backtrace, *exceptions, &code) ⇒ Object
- #dsl_exec_common(file, proxied_object, context, full_backtrace, *exceptions, &code) ⇒ Object
- #eval_dsl(text, proxied_object, context, full_backtrace, *exceptions) ⇒ Object
- #eval_dsl_block(block, proxied_object, context, full_backtrace, *exceptions) ⇒ Object
-
#eval_dsl_file(file, proxied_object, context, full_backtrace, *exceptions, &block) ⇒ Object
Load the given file by eval-ing it in the provided binding.
- #eval_dsl_file_content(file, file_content, proxied_object, context, full_backtrace, *exceptions) ⇒ Object
-
#filter_options(options, *user_option_spec) ⇒ Object
Partitions an option hash between known arguments and unknown arguments, with default value support.
- #filter_options_handle_single_entry(known_options, options, key) ⇒ Object
-
#load_dsl_file(file, *args, &block) ⇒ Object
Same than eval_dsl_file, but will not load the same file twice.
- #load_dsl_filter_backtrace(file, full_backtrace = false, *exceptions) ⇒ Object
-
#normalize_options(options) ⇒ Object
Normalizes all keys in the given option hash to symbol and returns the modified hash.
-
#null_enum ⇒ Object
returns always the same null enumerator, to avoid creating objects.
-
#poll(cycle) ⇒ Object
Yields every
cycle
seconds. -
#require_dir(filename, exclude = nil) ⇒ Object
Require all .rb files in the
filename
directory. -
#validate_option(options, name, required, message = nil) ⇒ Object
call-seq: validate_option(options, name, required, message) { |v| … } validate_option(options, name, required, message).
-
#validate_options(options, *known_options) ⇒ Object
Validates an option hash, with default value support.
-
#wait_until(cycle) ⇒ Object
Yields every
cycle
seconds until the block returns true. -
#wait_while(cycle) ⇒ Object
Yields every
cycle
seconds until the block returns false. - #with_module(*consts, &block) ⇒ Object
Class Method Details
.backtrace_remove_first_occurence_of(e, rx) ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 |
# File 'lib/utilrb/kernel/load_dsl_file.rb', line 5 def self.backtrace_remove_first_occurence_of(e, rx) # Remove the first occurence of eval_dsl_file_content in the backtrace backtrace = e.backtrace.dup found = false backtrace.delete_if do |line| break if found line =~ rx found = true end raise e, e., e.backtrace end |
Instance Method Details
#check_arity(object, arity, strict: nil) ⇒ Object
Raises if object
can accept calls with exactly arity
arguments. object should respond to #arity
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# File 'lib/utilrb/kernel/arity.rb', line 4 def check_arity(object, arity, strict: nil) if strict.nil? if object.respond_to?(:lambda?) strict = object.lambda? else strict = true end end if strict if object.arity >= 0 && object.arity != arity raise ArgumentError, "#{object} requests #{object.arity} arguments, but #{arity} was requested" elsif -object.arity-1 > arity raise ArgumentError, "#{object} requests at least #{object.arity} arguments, but #{arity} was requested" end end end |
#dsl_exec(proxied_object, context, full_backtrace, *exceptions, &code) ⇒ Object
145 146 147 |
# File 'lib/utilrb/kernel/load_dsl_file.rb', line 145 def dsl_exec(proxied_object, context, full_backtrace, *exceptions, &code) dsl_exec_common(nil, proxied_object, context, full_backtrace, *exceptions, &code) end |
#dsl_exec_common(file, proxied_object, context, full_backtrace, *exceptions, &code) ⇒ Object
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 187 188 189 190 191 192 193 194 195 |
# File 'lib/utilrb/kernel/load_dsl_file.rb', line 149 def dsl_exec_common(file, proxied_object, context, full_backtrace, *exceptions, &code) load_dsl_filter_backtrace(file, full_backtrace, *exceptions) do sandbox = with_module(*context) do Class.new(BasicObject) do def self.name; "" end attr_accessor :main_object def initialize(obj); @main_object = obj end def method_missing(*m, &block) main_object.__send__(*m, &block) end end end old_constants, new_constants = Kernel.constants, nil sandbox = sandbox.new(proxied_object) sandbox.with_module(*context) do old_constants = if respond_to?(:constants) constants else self.class.constants end instance_eval(&code) new_constants = if respond_to?(:constants) constants else self.class.constants end end # Check if the user defined new constants by using class K and/or # mod Mod if !new_constants new_constants = Kernel.constants end new_constants -= old_constants new_constants.delete_if { |n| n.to_s == 'WithModuleConstResolutionExtension' } if !new_constants.empty? msg = "#{new_constants.first} does not exist. You cannot define new constants in this context" raise NameError.new(msg, new_constants.first) end true end end |
#eval_dsl(text, proxied_object, context, full_backtrace, *exceptions) ⇒ Object
93 94 95 |
# File 'lib/utilrb/kernel/load_dsl_file.rb', line 93 def eval_dsl(text, proxied_object, context, full_backtrace, *exceptions) eval_dsl_file_content(nil, text, proxied_object, context, full_backtrace, *exceptions) end |
#eval_dsl_block(block, proxied_object, context, full_backtrace, *exceptions) ⇒ Object
86 87 88 89 90 91 |
# File 'lib/utilrb/kernel/load_dsl_file.rb', line 86 def eval_dsl_block(block, proxied_object, context, full_backtrace, *exceptions) load_dsl_filter_backtrace(nil, full_backtrace, *exceptions) do proxied_object.with_module(*context, &block) true end end |
#eval_dsl_file(file, proxied_object, context, full_backtrace, *exceptions, &block) ⇒ Object
Load the given file by eval-ing it in the provided binding. The originality of this method is to translate errors that are detected in the eval’ed code into errors that refer to the provided file
The caller of this method should call it at the end of its definition file, or the translation method may not be robust at all
118 119 120 121 122 123 124 125 126 |
# File 'lib/utilrb/kernel/load_dsl_file.rb', line 118 def eval_dsl_file(file, proxied_object, context, full_backtrace, *exceptions, &block) file = File.(file) if !File.readable?(file) raise ArgumentError, "#{file} does not exist" end file_content = File.read(file) eval_dsl_file_content(file, file_content, proxied_object, context, full_backtrace, *exceptions, &block) end |
#eval_dsl_file_content(file, file_content, proxied_object, context, full_backtrace, *exceptions) ⇒ Object
97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/utilrb/kernel/load_dsl_file.rb', line 97 def eval_dsl_file_content(file, file_content, proxied_object, context, full_backtrace, *exceptions) code = with_module(*context) do code = <<-EOD Proc.new { #{file_content} } EOD if file eval code, binding, file, 1 else eval code, binding end end dsl_exec_common(file, proxied_object, context, full_backtrace, *exceptions, &code) end |
#filter_options(options, *user_option_spec) ⇒ Object
Partitions an option hash between known arguments and unknown arguments, with default value support. All option keys are converted to symbols for consistency.
The following rules apply:
* if a hash is given, non-nil values are treated as default values.
* an array is equivalent to a hash where all values are 'nil'
See #validate_options and #filter_and_validate_options
call-seq:
filter_options(option, hash) -> known, unknown
filter_options(option, array) -> known, unknown
filter_options(nil, known_options) -> default_options, {}
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/utilrb/kernel/options.rb', line 32 def (, *user_option_spec) = .dup = Hash.new user_option_spec.each do |opt| if opt.respond_to?(:to_hash) opt.each do |key, value| if (, , key) if !value.nil? [key.to_sym] = value end end end elsif opt.respond_to?(:to_ary) opt.each do |key| (, , key) end else (, , opt) end end return *[, ] end |
#filter_options_handle_single_entry(known_options, options, key) ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 15 |
# File 'lib/utilrb/kernel/options.rb', line 4 def (, , key) key = key.to_sym if .has_key?(key) [key] = .delete(key) false elsif .has_key?(key_s = key.to_s) [key] = .delete(key_s) false else true end end |
#load_dsl_file(file, *args, &block) ⇒ Object
Same than eval_dsl_file, but will not load the same file twice
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/utilrb/kernel/load_dsl_file.rb', line 129 def load_dsl_file(file, *args, &block) file = File.(file) if $LOADED_FEATURES.include?(file) return false end $LOADED_FEATURES << file begin eval_dsl_file(file, *args, &block) rescue Exception $LOADED_FEATURES.delete(file) raise end true end |
#load_dsl_filter_backtrace(file, full_backtrace = false, *exceptions) ⇒ Object
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 |
# File 'lib/utilrb/kernel/load_dsl_file.rb', line 17 def load_dsl_filter_backtrace(file, full_backtrace = false, *exceptions) # Compute the position of the dsl-loading method that called us, so that # we don't touch anything below that while we are filtering the # backtrace if !full_backtrace callers = caller our_frame_pos = caller.size callers.each do |line| if line != /load_dsl_file\.rb/ our_frame_pos -= 1 else break end end end yield rescue Exception => e raise e if full_backtrace if exceptions.any? { |e_class| e.kind_of?(e_class) } raise e end backtrace = e.backtrace.dup = e..dup # Filter out the message ... it can contain backtrace information as # well (!) = .split("\n").map do |line| if line =~ /^.*:\d+(:.*)$/ backtrace.unshift line nil else line end end.compact.join("\n") if .empty? = backtrace.shift if =~ /^(\s*[^\s]+:\d+:)\s*(.*)/ location = $1 = $2 backtrace.unshift location else backtrace.unshift end end filtered_backtrace = backtrace[0, backtrace.size - our_frame_pos]. map do |line| line = line.gsub(/:in `.*dsl.*'/, '') if line =~ /load_dsl_file.*(method_missing|send)/ next end if line =~ /(load_dsl_file\.rb|with_module\.rb):\d+/ next else line end end.compact backtrace = (filtered_backtrace[0, 1] + filtered_backtrace + backtrace[(backtrace.size - our_frame_pos)..-1]) raise e, , backtrace end |
#normalize_options(options) ⇒ Object
Normalizes all keys in the given option hash to symbol and returns the modified hash
58 59 60 |
# File 'lib/utilrb/kernel/options.rb', line 58 def () .to_sym_keys end |
#null_enum ⇒ Object
returns always the same null enumerator, to avoid creating objects. It can be used as a seed to #inject:
enumerators.inject(null_enum) { |a, b| a + b }.each do |element|
end
16 17 18 |
# File 'lib/utilrb/enumerable/null.rb', line 16 def null_enum @@null_enumerator ||= NullEnumerator.new.freeze end |
#poll(cycle) ⇒ Object
Yields every cycle
seconds
3 4 5 6 7 8 |
# File 'lib/utilrb/kernel/poll.rb', line 3 def poll(cycle) loop do yield sleep(cycle) end end |
#require_dir(filename, exclude = nil) ⇒ Object
Require all .rb files in the filename
directory
3 4 5 6 7 8 9 10 11 |
# File 'lib/utilrb/kernel/require.rb', line 3 def require_dir(filename, exclude = nil) dirname = filename.gsub(/.rb$/, '') Dir.new(dirname).each do |file| next if exclude && exclude === file if file =~ /\.rb$/ require File.join(dirname, file) end end end |
#validate_option(options, name, required, message = nil) ⇒ Object
call-seq: validate_option(options, name, required, message) { |v| … } validate_option(options, name, required, message)
Validates option name
in the options
hash. If required is true, raises ArgumentError if the option is not present. Otherwise, yields its value to an optional block, which should return if the value is valid, or false otherwise. If the value is invalid, raises ArgumentError with message
or a standard message.
90 91 92 93 94 95 96 97 98 |
# File 'lib/utilrb/kernel/options.rb', line 90 def validate_option(, name, required, = nil) if required && !.has_key?(name) raise ArgumentError, "missing required option #{name}" elsif .has_key?(name) && block_given? if !yield([name]) raise ArgumentError, ( || "invalid option value #{[name]} for #{name}") end end end |
#validate_options(options, *known_options) ⇒ Object
Validates an option hash, with default value support. See #filter_options
In the first form, option_hash
should contain keys which are also in known_hash. The non-nil values of known_hash
are used as default values. In the second form, known_array
is an array of option keys. option_hash
keys shall be in known_array
. nil
is treated as an empty option hash, all keys are converted into symbols.
70 71 72 73 74 75 76 77 78 79 |
# File 'lib/utilrb/kernel/options.rb', line 70 def (, *) ||= Hash.new opt, unknown = Kernel.(.to_hash, *) unless unknown.empty? not_valid = unknown.keys.map { |m| "'#{m}'" }.join(" ") raise ArgumentError, "unknown options #{not_valid}", caller(1) end opt end |
#wait_until(cycle) ⇒ Object
Yields every cycle
seconds until the block returns true.
11 12 13 14 15 |
# File 'lib/utilrb/kernel/poll.rb', line 11 def wait_until(cycle) until yield sleep(cycle) end end |
#wait_while(cycle) ⇒ Object
Yields every cycle
seconds until the block returns false.
18 19 20 21 22 |
# File 'lib/utilrb/kernel/poll.rb', line 18 def wait_while(cycle) while yield sleep(cycle) end end |
#with_module(*consts, &block) ⇒ Object
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/utilrb/kernel/with_module.rb', line 18 def with_module(*consts, &block) Thread.current[:__with_module__] ||= Array.new Thread.current[:__with_module__].push consts Kernel.send(:extend, WithModuleConstResolutionExtension) Object.extend WithModuleConstResolutionExtension eval_string = if !block_given? && consts.last.respond_to?(:to_str) consts.pop end if eval_string instance_eval(eval_string) else instance_eval(&block) end ensure Thread.current[:__with_module__].pop end |