1 # depends on: module.rb kernel.rb
4 # Namespace for coercion functions between various ruby objects.
9 # Returns an object of given class. If given object already is one, it is
10 # returned. Otherwise tries obj.meth and returns the result if it is of the
11 # right kind. TypeErrors are raised if the conversion method fails or the
12 # conversion result is wrong.
14 # Uses Type.obj_kind_of to bypass type check overrides.
16 # Equivalent to MRI's rb_convert_type().
18 def self.coerce_to(obj, cls, meth)
19 return obj if self.obj_kind_of?(obj, cls)
22 ret = obj.__send__(meth)
24 raise TypeError, "Coercion error: #{obj.inspect}.#{meth} => #{cls} failed:\n" \
28 return ret if self.obj_kind_of?(ret, cls)
30 raise TypeError, "Coercion error: obj.#{meth} did NOT return a #{cls} (was #{ret.class})"
37 raise TypeError, "can't convert nil into Float" if obj.nil?
40 if obj !~ /^(\+|\-)?\d+$/ && obj !~ /^(\+|\-)?(\d_?)*\.(\d_?)+$/ && obj !~ /^[-+]?\d*\.?\d*e[-+]\d*\.?\d*/
41 raise ArgumentError, "invalid value for Float(): #{obj.inspect}"
45 Type.coerce_to(obj, Float, :to_f)
47 module_function :Float
50 return obj.to_inum(0, true) if obj.is_a?(String)
51 method = obj.respond_to?(:to_int) ? :to_int : :to_i
52 Type.coerce_to(obj, Integer, method)
54 module_function :Integer
57 if obj.respond_to?(:to_ary)
58 Type.coerce_to(obj, Array, :to_ary)
59 elsif obj.respond_to?(:to_a)
60 Type.coerce_to(obj, Array, :to_a)
65 module_function :Array
68 Type.coerce_to(obj, String, :to_s)
70 module_function :String
73 # MRI uses a macro named StringValue which has essentially the same
74 # semantics as obj.coerce_to(String, :to_str), but rather than using that
75 # long construction everywhere, we define a private method similar to
78 # Another possibility would be to change String() as follows:
80 # String(obj, sym=:to_s)
82 # and use String(obj, :to_str) instead of StringValue(obj)
85 Type.coerce_to(obj, String, :to_str)
90 # MRI uses a macro named NUM2DBL which has essentially the same semantics as
91 # Float(), with the difference that it raises a TypeError and not a
92 # ArgumentError. It is only used in a few places (in MRI and Rubinius).
94 # If we can, we should probably get rid of this.
100 raise TypeError, 'no implicit conversion to float'
107 # HACK :: added due to broken constant lookup rules
110 def raise(exc=Undefined, msg=nil, trace=nil)
112 if exc.equal? Undefined
117 exc = RuntimeError.new("No current exception")
119 elsif exc.respond_to? :exception
120 exc = exc.exception msg
121 raise ::TypeError, 'exception class/object expected' unless exc.kind_of?(::Exception)
122 exc.set_backtrace trace if trace
123 elsif exc.kind_of? String or !exc
124 exc = ::RuntimeError.exception exc
126 raise ::TypeError, 'exception class/object expected'
129 if $DEBUG and $VERBOSE != nil
130 sender = MethodContext.current.sender
131 STDERR.puts "Exception: `#{exc.class}' #{sender.location} - #{exc.message}"
135 exc.context = MethodContext.current.sender unless exc.context
137 Rubinius.asm(exc) { |e| e.bytecode(self); raise_exc }
139 module_function :raise
141 alias_method :fail, :raise
142 module_function :fail
145 $stderr.write "#{warning}\n" unless $VERBOSE.nil?
148 module_function :warn
151 code = 0 if code.equal? true
152 raise SystemExit.new(code)
154 module_function :exit
159 module_function :exit!
164 module_function :abort
166 def printf(target, *args)
167 if target.kind_of? IO
169 elsif target.kind_of? String
170 $stdout << Sprintf.new(target, *args).parse
172 raise TypeError, "The first arg to printf should be an IO or a String"
176 module_function :printf
178 def sprintf(str, *args)
179 Sprintf.new(str, *args).parse
181 alias_method :format, :sprintf
182 module_function :sprintf
183 module_function :format
184 module_function :abort
190 module_function :puts
192 # For each object given, prints obj.inspect followed by the
193 # system record separator to standard output (thus, separator
194 # cannot be overridden.) Prints nothing if no objects given.
196 return nil if a.empty?
197 a.each { |obj| $stdout.puts obj.inspect }
204 $stdout.write obj.to_s
208 module_function :print
210 def open(path, *rest, &block)
211 path = StringValue(path)
213 if path.kind_of? String and path.prefix? '|'
214 return IO.popen(path[1..-1], *rest, &block)
217 File.open(path, *rest, &block)
219 module_function :open
222 # NOTE: This isn't quite MRI compatible.
223 # We don't seed the RNG by default with a combination of time, pid and
228 cur = Kernel.current_srand
229 Platform::POSIX.srand(seed.to_i)
230 Kernel.current_srand = seed.to_i
233 module_function :srand
236 def self.current_srand
240 def self.current_srand=(val)
246 x = Platform::POSIX.rand
247 # scale result of rand to a domain between 0 and max
252 x / (0x7fffffff / max)
254 x * (max / 0x7fffffff)
258 module_function :rand
261 order == Rubinius::ENDIAN
263 module_function :endian?
266 if MethodContext.current.sender.block
272 module_function :block_given?
274 alias_method :iterator?, :block_given?
275 module_function :iterator?
279 raise ArgumentError, "block required" if block.nil?
281 block.disable_long_return!
283 return Proc::Function.__from_block__(block)
285 alias_method :proc, :lambda
286 module_function :lambda
287 module_function :proc
290 frame = MethodContext.current.sender
291 frame.stack_trace_starting_at(start)
293 module_function :caller
296 Globals.variables.map { |i| i.to_s }
298 module_function :global_variables
301 raise LocalJumpError, "no block given" unless block_given?
307 module_function :loop
310 # Sleeps the current thread for +duration+ seconds.
312 def sleep(duration = Undefined)
315 # No duration means we sleep forever. By not registering anything with
316 # Scheduler, the receive call will effectively block until someone
317 # explicitely wakes this thread.
318 unless duration.equal?(Undefined)
319 raise TypeError, 'time interval must be a numeric value' unless duration.kind_of?(Numeric)
320 duration = Time.at duration
321 Scheduler.send_in_seconds(chan, duration.to_f, nil)
324 return (Time.now - start).round
326 module_function :sleep
329 Rubinius::AtExit.unshift(block)
331 module_function :at_exit
333 def test(cmd, file1, file2=nil)
336 File.directory? file1
345 module_function :test
347 def trap(sig, prc=nil, &block)
348 Signal.trap(sig, prc, &block)
350 module_function :trap
352 def initialize_copy(other)
355 private :initialize_copy
357 alias_method :__id__, :object_id
359 alias_method :==, :equal?
361 # The "sorta" operator, also known as the case equality operator.
362 # Generally while #eql? and #== are stricter, #=== is often used
363 # to denote an acceptable match or inclusion. It returns true if
364 # the match is considered to be valid and false otherwise. It has
365 # one special purpose: it is the operator used by the case expression.
366 # So in this expression:
375 # What really happens is that `/Foo/ === obj` is attempted and so
376 # on down until a match is found or the expression ends. The use
377 # by Regexp is very illustrative: while obj may satisfy the pattern,
378 # it may not be the only option.
380 # The default #=== operator checks if the other object is #equal?
381 # to this one (i.e., is the same object) or if #== returns true.
382 # If neither is true, false is returned instead. Many classes opt
383 # to override this behaviour to take advantage of its use in a
384 # case expression and to implement more relaxed matching semantics.
385 # Notably, the above Regexp as well as String, Module and many others.
387 equal?(other) || self == other
391 # Regexp matching fails by default but may be overridden by subclasses,
392 # notably Regexp and String.
398 def class_variable_get(sym)
399 self.class.class_variable_get sym
402 def class_variable_set(sym, value)
403 self.class.class_variable_set sym, value
406 def class_variables(symbols = false)
407 self.class.class_variables(symbols)
411 # \_\_const_set__ is emitted by the compiler for const assignment
414 # This is the catch-all version for unwanted values
416 def __const_set__(name, obj)
417 raise TypeError, "#{self} is not a class/module"
421 # Activates the singleton Debugger instance, and sets a breakpoint
422 # immediately after the call site to this method.
424 # TODO: Have method take an options hash to configure debugger behavior,
425 # and perhaps a block containing debugger commands to be executed when the
429 require 'debugger/debugger'
430 dbg = Debugger.instance
433 # Default to command-line interface if nothing registered
434 require 'debugger/interface'
435 Debugger::CmdLineInterface.new
438 ctxt = MethodContext.current.sender
441 bp = dbg.get_breakpoint(cm, ip)
443 bp.enable unless bp.enabled?
445 bp = dbg.set_breakpoint(cm, ip)
448 # Modify send site not to call this method again
449 bc = ctxt.method.bytecodes
451 Breakpoint.encoder.replace_instruction(bc, ip-4, [:noop])
452 Breakpoint.encoder.replace_instruction(bc, ip-2, [:noop])
457 alias_method :breakpoint, :debugger
459 alias_method :eql?, :equal?
462 modules.reverse_each do |mod|
463 mod.extend_object(self)
464 mod.send(:extended, self)
469 def inspect(prefix=nil, vars=nil)
470 return "..." if RecursionGuard.inspecting?(self)
474 return self.to_s unless iv
476 if (iv.is_a?(Hash) or iv.is_a?(Tuple)) and iv.empty?
480 prefix = "#{self.class}:0x#{self.object_id.to_s(16)}" unless prefix
483 RecursionGuard.inspect(self) do
487 next if vars and !vars.include?(k)
488 parts << "#{k}=#{v.inspect}"
491 0.step(iv.size - 1, 2) do |i|
493 next if vars and !vars.include?(k)
495 parts << "#{k}=#{v.inspect}"
505 "#<#{prefix} #{parts.join(' ')}>"
511 # obj.instance_exec(arg, ...) { |var,...| block } => obj
513 # Executes the given block within the context of the receiver +obj+. In
514 # order to set the context, the variable +self+ is set to +obj+ while the
515 # code is executing, giving the code access to +obj+'s instance variables.
517 # Arguments are passed as block parameters.
526 # k.instance_exec(5) {|x| @secret+x } #=> 104
528 def instance_exec(*args, &prc)
529 raise ArgumentError, "Missing block" unless block_given?
530 env = prc.block.redirect_to self
531 env.method.staticscope = StaticScope.new(metaclass, env.method.staticscope)
536 # Returns true if this object is an instance of the given class, otherwise
537 # false. Raises a TypeError if a non-Class object given.
539 # Module objects can also be given for MRI compatibility but the result is
542 def instance_of?(cls)
543 if cls.class != Class and cls.class != Module
544 # We can obviously compare against Modules but result is always false
545 raise TypeError, "instance_of? requires a Class argument"
551 def instance_variable_get(sym)
552 sym = instance_variable_validate(sym)
553 get_instance_variable(sym)
556 def instance_variable_set(sym, value)
557 sym = instance_variable_validate(sym)
558 set_instance_variable(sym, value)
561 def remove_instance_variable(sym)
563 instance_variable_set(sym, nil)
565 private :remove_instance_variable
567 def instance_variables
568 vars = get_instance_variables
569 return [] if vars.nil?
572 if vars.kind_of? Tuple
574 0.step(vars.size - 1, 2) do |i|
585 return vars.keys.collect { |v| v.to_s }
588 def instance_variable_defined?(name)
589 name = instance_variable_validate(name)
591 vars = get_instance_variables
592 return false unless vars
595 if vars.kind_of? Tuple
597 0.step(vars.size - 1, 2) do |i|
599 return true if k == name
605 return vars.key?(name)
608 # Both of these are for defined? when used inside a proxy obj that
609 # may undef the regular method. The compiler generates __ calls.
610 alias_method :__instance_variable_defined_eh__, :instance_variable_defined?
611 alias_method :__respond_to_eh__, :respond_to?
613 def singleton_method_added(name)
615 private :singleton_method_added
617 def singleton_method_removed(name)
619 private :singleton_method_removed
621 def singleton_method_undefined(name)
623 private :singleton_method_undefined
625 alias_method :is_a?, :kind_of?
628 cm = __find_method__(name)
631 return Method.new(self, cm[1], cm[0])
633 raise NameError, "undefined method `#{name}' for #{self.inspect}"
641 def method_missing_cv(meth, *args)
642 # Exclude method_missing from the backtrace since it only confuses
644 myself = MethodContext.current
647 if myself.send_private?
648 raise NameError, "undefined local variable or method `#{meth}' for #{inspect}"
649 elsif self.__kind_of__ Class or self.__kind_of__ Module
650 raise NoMethodError.new("No method '#{meth}' on #{self} (#{self.__class__})", ctx, args)
652 raise NoMethodError.new("No method '#{meth}' on an instance of #{self.__class__}.", ctx, args)
656 private :method_missing_cv
658 def methods(all=true)
659 names = singleton_methods(all)
660 names |= self.class.instance_methods(true) if all
664 def private_methods(all=true)
665 names = private_singleton_methods
666 names |= self.class.private_instance_methods(all)
670 def private_singleton_methods
671 metaclass.method_table.private_names.map { |meth| meth.to_s }
674 def protected_methods(all=true)
675 names = protected_singleton_methods
676 names |= self.class.protected_instance_methods(all)
680 def protected_singleton_methods
681 metaclass.method_table.protected_names.map { |meth| meth.to_s }
684 def public_methods(all=true)
685 names = singleton_methods(all)
686 names |= self.class.public_instance_methods(all)
690 def singleton_methods(all=true)
691 mt = metaclass.method_table
693 return mt.keys.map { |m| m.to_s }
695 (mt.public_names + mt.protected_names).map { |m| m.to_s }
699 alias_method :send, :__send__
702 if self.kind_of? Array
710 "#<#{self.__class__}:0x#{self.__id__.to_s(16)}>"
713 def autoload(name, file)
714 Object.autoload(name, file)
719 Object.autoload?(name)
723 def set_trace_func(*args)
724 raise NotImplementedError
726 module_function :set_trace_func
729 raise NotImplementedError
731 module_function :syscall
734 raise NotImplementedError
736 module_function :trace_var
738 def untrace_var(*args)
739 raise NotImplementedError
741 module_function :untrace_var
746 ensure_last_read_string
747 $_ = $_.chomp(string)
749 module_function :chomp
751 def chomp!(string=$/)
752 ensure_last_read_string
755 module_function :chomp!
758 ensure_last_read_string
761 module_function :chop
764 ensure_last_read_string
767 module_function :chop!
772 module_function :getc
777 module_function :putc
780 # HACK. Needs to use ARGF first.
783 module_function :gets
788 module_function :readline
791 $stdin.readlines(sep)
793 module_function :readlines
795 def gsub(pattern, rep=nil, &block)
796 ensure_last_read_string
797 $_ = $_.gsub(pattern, rep, &block)
799 module_function :gsub
801 def gsub!(pattern, rep=nil, &block)
802 ensure_last_read_string
803 $_.gsub!(pattern, rep, &block)
805 module_function :gsub!
807 def sub(pattern, rep=nil, &block)
808 ensure_last_read_string
809 $_ = $_.sub(pattern, rep, &block)
813 def sub!(pattern, rep=nil, &block)
814 ensure_last_read_string
815 $_.sub!(pattern, rep, &block)
817 module_function :sub!
819 def scan(pattern, &block)
820 ensure_last_read_string
821 $_.scan(pattern, &block)
823 module_function :scan
828 module_function :select
831 ensure_last_read_string
834 module_function :split
836 # Checks whether the "last read line" $_ variable is a String,
837 # raising a TypeError when not.
838 def ensure_last_read_string
839 unless $_.kind_of? String
840 cls = $_.nil? ? "nil" : $_.class
841 raise TypeError, "$_ must be a String (#{cls} given)"
844 module_function :ensure_last_read_string
845 private :ensure_last_read_string
848 private :get_instance_variable
849 private :get_instance_variables
850 private :set_instance_variable
852 def self.after_loaded
853 alias_method :method_missing, :method_missing_cv
855 # Add in $! in as a hook, to just do $!. This is for accesses to $!
856 # that the compiler can't see.
858 Globals.set_hook(:$!, get, nil)
860 # Same as $!, for any accesses we might miss.
861 # HACK. I doubt this is correct, because of how it will be called.
862 get = proc { Regex.last_match }
863 Globals.set_hook(:$~, get, nil)
866 Globals.set_hook(:$*, get, nil)
868 get = proc { $! ? $!.backtrace : nil }
869 Globals.set_hook(:$@, get, nil)
871 get = proc { Process.pid }
872 Globals.set_hook(:$$, get, nil)
877 class SystemExit < Exception
878 def initialize(status)
885 "System is exiting with code '#{status}'"