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) ⇒ 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.
-
#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
6 7 8 9 10 11 12 13 14 15 16 |
# File 'lib/utilrb/kernel/load_dsl_file.rb', line 6 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) ⇒ 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 |
# File 'lib/utilrb/kernel/arity.rb', line 4 def check_arity(object, arity) if object.respond_to?(:lambda?) # For ruby 1.9 compatibility on blocks without arguments if !object.lambda? && object.arity == 0 return end end unless object.arity == arity || (object.arity < 0 && object.arity > - arity - 2) raise ArgumentError, "#{object} does not accept to be called with #{arity} argument(s)", caller(2) end end |
#dsl_exec(proxied_object, context, full_backtrace, *exceptions, &code) ⇒ Object
146 147 148 |
# File 'lib/utilrb/kernel/load_dsl_file.rb', line 146 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
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 196 197 198 199 |
# File 'lib/utilrb/kernel/load_dsl_file.rb', line 150 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 = nil if !Utilrb::RUBY_IS_191 old_constants = Kernel.constants end 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 !Utilrb::RUBY_IS_191 && !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
94 95 96 |
# File 'lib/utilrb/kernel/load_dsl_file.rb', line 94 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
87 88 89 90 91 92 |
# File 'lib/utilrb/kernel/load_dsl_file.rb', line 87 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
119 120 121 122 123 124 125 126 127 |
# File 'lib/utilrb/kernel/load_dsl_file.rb', line 119 def eval_dsl_file(file, proxied_object, context, full_backtrace, *exceptions, &block) if !File.readable?(file) raise ArgumentError, "#{file} does not exist" end loaded_file = file.gsub(/^#{Regexp.quote(Dir.pwd)}\//, '') file_content = File.read(file) eval_dsl_file_content(loaded_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
98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/utilrb/kernel/load_dsl_file.rb', line 98 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, {}
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 |
# File 'lib/utilrb/kernel/options.rb', line 19 def (, *user_option_spec) option_spec = Hash.new user_option_spec.each do |opt| if opt.respond_to?(:to_hash) option_spec.merge!(opt) elsif opt.respond_to?(:to_ary) opt.each do |key| option_spec[key] = nil end else option_spec[opt] = nil end end = Hash.new = .dup .delete_if do |key, value| if !key.respond_to?(:to_sym) [key] = value true end end = (.to_hash || Hash.new).to_sym_keys # cannot use #to_sym_keys as option_spec can be an array option_spec = option_spec.inject({}) { |h, (k, v)| h[k.to_sym] = v; h } .merge!(.slice(*(.keys - option_spec.keys))) = .slice(*option_spec.keys) # Set default values defined in the spec option_spec.each_key do |k| value = option_spec[k] if !.has_key?(k) && !value.nil? [k] ||= value end end return *[, ] end |
#load_dsl_file(file, *args, &block) ⇒ Object
Same than eval_dsl_file, but will not load the same file twice
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/utilrb/kernel/load_dsl_file.rb', line 130 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
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 |
# File 'lib/utilrb/kernel/load_dsl_file.rb', line 18 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.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
62 63 64 |
# File 'lib/utilrb/kernel/options.rb', line 62 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.
94 95 96 97 98 99 100 101 102 |
# File 'lib/utilrb/kernel/options.rb', line 94 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.
74 75 76 77 78 79 80 81 82 83 |
# File 'lib/utilrb/kernel/options.rb', line 74 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
4 5 6 7 8 9 10 11 12 13 14 15 |
# File 'lib/utilrb/kernel/with_module.rb', line 4 def with_module(*consts, &blk) slf = self l = if !block_given? && consts.last.respond_to?(:to_str) eval_string = consts.pop lambda { slf.instance_eval(eval_string) } else lambda { slf.instance_eval(&blk) } end consts.inject(l) {|l, k| lambda { k.class_eval(&l) } }.call end |