1 # depends on: module.rb kernel.rb
6 # Returns an object of given class. If given object already is one, it is
7 # returned. Otherwise tries obj.meth and returns the result if it is of the
8 # right kind. TypeErrors are raised if the conversion method fails or the
9 # conversion result is wrong.
11 # Uses Type.obj_kind_of to bypass type check overrides.
13 def self.coerce_to(obj, cls, meth)
14 return obj if self.obj_kind_of?(obj, cls)
17 ret = obj.__send__(meth)
19 raise TypeError, "Coercion error: #{obj.inspect}.#{meth} => #{cls} failed:\n" \
23 return ret if self.obj_kind_of?(ret, cls)
25 raise TypeError, "Coercion error: obj.#{meth} did NOT return a #{cls} (was #{ret.class})"
32 raise TypeError, "can't convert nil into Float" if obj.nil?
35 if obj !~ /^(\+|\-)?\d+$/ && obj !~ /^(\+|\-)?(\d_?)*\.(\d_?)+$/ && obj !~ /^[-+]?\d*\.?\d*e[-+]\d*\.?\d*/
36 raise ArgumentError, "invalid value for Float(): #{obj.inspect}"
40 Type.coerce_to(obj, Float, :to_f)
42 module_function :Float
45 return obj.to_inum(0, true) if obj.is_a?(String)
46 method = obj.respond_to?(:to_int) ? :to_int : :to_i
47 Type.coerce_to(obj, Integer, method)
49 module_function :Integer
52 if obj.respond_to?(:to_ary)
53 Type.coerce_to(obj, Array, :to_ary)
54 elsif obj.respond_to?(:to_a)
55 Type.coerce_to(obj, Array, :to_a)
60 module_function :Array
63 Type.coerce_to(obj, String, :to_s)
65 module_function :String
68 # MRI uses a macro named StringValue which has essentially the same
69 # semantics as obj.coerce_to(String, :to_str), but rather than using that
70 # long construction everywhere, we define a private method similar to
73 # Another possibility would be to change String() as follows:
75 # String(obj, sym=:to_s)
77 # and use String(obj, :to_str) instead of StringValue(obj)
80 Type.coerce_to(obj, String, :to_str)
85 # MRI uses a macro named NUM2DBL which has essentially the same semantics as
86 # Float(), with the difference that it raises a TypeError and not a
87 # ArgumentError. It is only used in a few places (in MRI and Rubinius).
89 # If we can, we should probably get rid of this.
95 raise TypeError, 'no implicit conversion to float'
102 # HACK :: added due to broken constant lookup rules
105 def raise(exc=Undefined, msg=nil, trace=nil)
107 if exc.equal? Undefined
112 exc = RuntimeError.new("No current exception")
114 elsif exc.respond_to? :exception
115 exc = exc.exception msg
116 raise ::TypeError, 'exception class/object expected' unless exc.kind_of?(::Exception)
117 exc.set_backtrace trace if trace
118 elsif exc.kind_of? String or !exc
119 exc = ::RuntimeError.exception exc
121 raise ::TypeError, 'exception class/object expected'
124 if $DEBUG and $VERBOSE != nil
125 sender = MethodContext.current.sender
126 STDERR.puts "Exception: `#{exc.class}' #{sender.location} - #{exc.message}"
130 exc.set_backtrace MethodContext.current.sender unless exc.context
132 Rubinius.asm(exc) { |e| e.bytecode(self); raise_exc }
134 module_function :raise
136 alias_method :fail, :raise
137 module_function :fail
141 $stderr.write MethodContext.current.sender.location
142 $stderr.write ": warning: "
143 $stderr.write warning
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_environment(block)
285 alias_method :proc, :lambda
286 module_function :lambda
287 module_function :proc
290 return MethodContext.current.sender.calling_hierarchy(start)
292 module_function :caller
295 Globals.variables.map { |i| i.to_s }
297 module_function :global_variables
300 raise LocalJumpError, "no block given" unless block_given?
306 module_function :loop
309 # Sleeps the current thread for +duration+ seconds.
311 def sleep(duration = Undefined)
314 # No duration means we sleep forever. By not registering anything with
315 # Scheduler, the receive call will effectively block until someone
316 # explicitely wakes this thread.
317 unless duration.equal?(Undefined)
318 raise TypeError, 'time interval must be a numeric value' unless duration.kind_of?(Numeric)
319 duration = Time.at duration
320 Scheduler.send_in_seconds(chan, duration.to_f, nil)
323 return (Time.now - start).round
325 module_function :sleep
328 Rubinius::AtExit.unshift(block)
330 module_function :at_exit
332 def test(cmd, file1, file2=nil)
335 File.directory? file1
344 module_function :test
346 def trap(sig, prc=nil, &block)
347 Signal.trap(sig, prc, &block)
349 module_function :trap
351 def initialize_copy(other)
354 private :initialize_copy
356 alias_method :__id__, :object_id
358 alias_method :==, :equal?
360 # The "sorta" operator, also known as the case equality operator.
361 # Generally while #eql? and #== are stricter, #=== is often used
362 # to denote an acceptable match or inclusion. It returns true if
363 # the match is considered to be valid and false otherwise. It has
364 # one special purpose: it is the operator used by the case expression.
365 # So in this expression:
374 # What really happens is that `/Foo/ === obj` is attempted and so
375 # on down until a match is found or the expression ends. The use
376 # by Regexp is very illustrative: while obj may satisfy the pattern,
377 # it may not be the only option.
379 # The default #=== operator checks if the other object is #equal?
380 # to this one (i.e., is the same object) or if #== returns true.
381 # If neither is true, false is returned instead. Many classes opt
382 # to override this behaviour to take advantage of its use in a
383 # case expression and to implement more relaxed matching semantics.
384 # Notably, the above Regexp as well as String, Module and many others.
386 equal?(other) || self == other
390 # Regexp matching fails by default but may be overridden by subclasses,
391 # notably Regexp and String.
397 def class_variable_get(sym)
398 self.class.class_variable_get sym
401 def class_variable_set(sym, value)
402 self.class.class_variable_set sym, value
405 def class_variables(symbols = false)
406 self.class.class_variables(symbols)
410 # \_\_const_set__ is emitted by the compiler for const assignment
413 # This is the catch-all version for unwanted values
415 def __const_set__(name, obj)
416 raise TypeError, "#{self} is not a class/module"
420 # Activates the singleton Debugger instance, and sets a breakpoint
421 # immediately after the call site to this method.
423 # TODO: Have method take an options hash to configure debugger behavior,
424 # and perhaps a block containing debugger commands to be executed when the
428 require 'debugger/debugger'
429 dbg = Debugger.instance
432 # Default to command-line interface if nothing registered
433 require 'debugger/interface'
434 Debugger::CmdLineInterface.new
437 ctxt = MethodContext.current.sender
440 bp = dbg.get_breakpoint(cm, ip)
442 bp.enable unless bp.enabled?
444 bp = dbg.set_breakpoint(cm, ip)
447 # Modify send site not to call this method again
448 bc = ctxt.method.bytecodes
450 Breakpoint.encoder.replace_instruction(bc, ip-4, [:noop])
451 Breakpoint.encoder.replace_instruction(bc, ip-2, [:noop])
456 alias_method :breakpoint, :debugger
458 alias_method :eql?, :equal?
461 modules.reverse_each do |mod|
462 mod.extend_object(self)
463 mod.send(:extended, self)
468 def inspect(prefix=nil, vars=nil)
469 return "..." if RecursionGuard.inspecting?(self)
473 return self.to_s unless iv
475 if (iv.is_a?(Hash) or iv.is_a?(Tuple)) and iv.empty?
479 prefix = "#{self.class}:0x#{self.object_id.to_s(16)}" unless prefix
482 RecursionGuard.inspect(self) do
486 next if vars and !vars.include?(k)
487 parts << "#{k}=#{v.inspect}"
490 0.step(iv.size - 1, 2) do |i|
492 next if vars and !vars.include?(k)
494 parts << "#{k}=#{v.inspect}"
504 "#<#{prefix} #{parts.join(' ')}>"
510 # obj.instance_exec(arg, ...) { |var,...| block } => obj
512 # Executes the given block within the context of the receiver +obj+. In
513 # order to set the context, the variable +self+ is set to +obj+ while the
514 # code is executing, giving the code access to +obj+'s instance variables.
516 # Arguments are passed as block parameters.
525 # k.instance_exec(5) {|x| @secret+x } #=> 104
527 def instance_exec(*args, &prc)
528 raise ArgumentError, "Missing block" unless block_given?
529 env = prc.block.redirect_to self
530 env.method.staticscope = StaticScope.new(metaclass, env.method.staticscope)
535 # Returns true if this object is an instance of the given class, otherwise
536 # false. Raises a TypeError if a non-Class object given.
538 # Module objects can also be given for MRI compatibility but the result is
541 def instance_of?(cls)
542 if cls.class != Class and cls.class != Module
543 # We can obviously compare against Modules but result is always false
544 raise TypeError, "instance_of? requires a Class argument"
550 def instance_variable_get(sym)
551 sym = instance_variable_validate(sym)
552 get_instance_variable(sym)
555 def instance_variable_set(sym, value)
556 sym = instance_variable_validate(sym)
557 set_instance_variable(sym, value)
560 def remove_instance_variable(sym)
562 instance_variable_set(sym, nil)
564 private :remove_instance_variable
566 def instance_variables
567 vars = get_instance_variables
568 return [] if vars.nil?
571 if vars.kind_of? Tuple
573 0.step(vars.size - 1, 2) do |i|
584 return vars.keys.collect { |v| v.to_s }
587 def instance_variable_defined?(name)
588 vars = get_instance_variables
589 return false unless vars
591 name = name.to_sym unless name.kind_of? Symbol
594 if vars.kind_of? Tuple
596 0.step(vars.size - 1, 2) do |i|
598 return true if k == name
604 return vars.key?(name)
607 # Both of these are for defined? when used inside a proxy obj that
608 # may undef the regular method. The compiler generates __ calls.
609 alias_method :__instance_variable_defined_eh__, :instance_variable_defined?
610 alias_method :__respond_to_eh__, :respond_to?
612 def singleton_method_added(name)
614 private :singleton_method_added
616 def singleton_method_removed(name)
618 private :singleton_method_removed
620 def singleton_method_undefined(name)
622 private :singleton_method_undefined
624 alias_method :is_a?, :kind_of?
627 cm = __find_method__(name)
630 return Method.new(self, cm[1], cm[0])
632 raise NameError, "undefined method `#{name}' for #{self.inspect}"
640 def method_missing_cv(meth, *args)
641 # Exclude method_missing from the backtrace since it only confuses
643 myself = MethodContext.current
646 if myself.send_private?
647 raise NameError, "undefined local variable or method `#{meth}' for #{inspect}"
648 elsif self.kind_of? Class or self.kind_of? Module
649 raise NoMethodError.new("No method '#{meth}' on #{self} (#{self.class})", ctx, args)
651 raise NoMethodError.new("No method '#{meth}' on an instance of #{self.class}.", ctx, args)
655 private :method_missing_cv
657 def methods(all=true)
658 names = singleton_methods(all)
659 names |= self.class.instance_methods(true) if all
663 def private_methods(all=true)
664 names = private_singleton_methods
665 names |= self.class.private_instance_methods(all)
669 def private_singleton_methods
670 metaclass.method_table.private_names.map { |meth| meth.to_s }
673 def protected_methods(all=true)
674 names = protected_singleton_methods
675 names |= self.class.protected_instance_methods(all)
679 def protected_singleton_methods
680 metaclass.method_table.protected_names.map { |meth| meth.to_s }
683 def public_methods(all=true)
684 names = singleton_methods(all)
685 names |= self.class.public_instance_methods(all)
689 def singleton_methods(all=true)
690 mt = metaclass.method_table
692 return mt.keys.map { |m| m.to_s }
694 (mt.public_names + mt.protected_names).map { |m| m.to_s }
698 alias_method :send, :__send__
701 if self.kind_of? Array
709 "#<#{self.class}:0x#{self.object_id.to_s(16)}>"
712 def autoload(name, file)
713 Object.autoload(name, file)
718 Object.autoload?(name)
722 def set_trace_func(*args)
723 raise NotImplementedError
725 module_function :set_trace_func
728 raise NotImplementedError
730 module_function :syscall
733 raise NotImplementedError
735 module_function :trace_var
737 def untrace_var(*args)
738 raise NotImplementedError
740 module_function :untrace_var
745 $_ = $_.chomp(string)
747 module_function :chomp
749 def chomp!(string=$/)
752 module_function :chomp!
757 module_function :chop
762 module_function :chop!
767 module_function :getc
772 module_function :putc
775 # HACK. Needs to use ARGF first.
778 module_function :gets
783 module_function :readline
786 $stdin.readlines(sep)
788 module_function :readlines
790 def gsub(pattern, rep=nil, &block)
791 $_ = $_.gsub(pattern, rep, &block)
793 module_function :gsub
795 def gsub!(pattern, rep=nil, &block)
796 $_.gsub!(pattern, rep, &block)
798 module_function :gsub!
800 def sub(pattern, rep=nil, &block)
801 $_ = $_.sub(pattern, rep, &block)
805 def sub!(pattern, rep=nil, &block)
806 $_.sub!(pattern, rep, &block)
808 module_function :sub!
810 def scan(pattern, &block)
811 $_.scan(pattern, &block)
813 module_function :scan
818 module_function :select
823 module_function :split
826 private :get_instance_variable
827 private :get_instance_variables
828 private :set_instance_variable
830 def self.after_loaded
831 alias_method :method_missing, :method_missing_cv
833 # Add in $! in as a hook, to just do $!. This is for accesses to $!
834 # that the compiler can't see.
836 Globals.set_hook(:$!, get, nil)
838 # Same as $!, for any accesses we might miss.
839 # HACK. I doubt this is correct, because of how it will be called.
840 get = proc { Regex.last_match }
841 Globals.set_hook(:$~, get, nil)
844 Globals.set_hook(:$*, get, nil)
846 get = proc { $! ? $!.backtrace : nil }
847 Globals.set_hook(:$@, get, nil)
849 get = proc { Process.pid }
850 Globals.set_hook(:$$, get, nil)
855 class SystemExit < Exception
856 def initialize(status)
863 "System is exiting with code '#{status}'"