Change soft-fail to use the config, rather than env
[rbx.git] / kernel / core / kernel.rb
blob49554c3326ae08d0c7b337eec0c4c97f2e2edac7
1 # depends on: module.rb kernel.rb
3 ##
4 # Namespace for coercion functions between various ruby objects.
6 module Type
8   ##
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.
13   #
14   # Uses Type.obj_kind_of to bypass type check overrides.
15   #
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)
21     begin
22       ret = obj.__send__(meth)
23     rescue Exception => e
24       raise TypeError, "Coercion error: #{obj.inspect}.#{meth} => #{cls} failed:\n" \
25                        "(#{e.message})"
26     end
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})"
31   end
32 end
34 module Kernel
36   def Float(obj)
37     raise TypeError, "can't convert nil into Float" if obj.nil?
39     if obj.is_a?(String)
40       if obj !~ /^(\+|\-)?\d+$/ && obj !~ /^(\+|\-)?(\d_?)*\.(\d_?)+$/ && obj !~ /^[-+]?\d*\.?\d*e[-+]\d*\.?\d*/
41         raise ArgumentError, "invalid value for Float(): #{obj.inspect}"
42       end
43     end
45     Type.coerce_to(obj, Float, :to_f)
46   end
47   module_function :Float
49   def Integer(obj)
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)
53   end
54   module_function :Integer
56   def Array(obj)
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)
61     else
62       [obj]
63     end
64   end
65   module_function :Array
67   def String(obj)
68     Type.coerce_to(obj, String, :to_s)
69   end
70   module_function :String
72   ##
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
76   # String().
77   #
78   # Another possibility would be to change String() as follows:
79   #
80   #   String(obj, sym=:to_s)
81   #
82   # and use String(obj, :to_str) instead of StringValue(obj)
84   def StringValue(obj)
85     Type.coerce_to(obj, String, :to_str)
86   end
87   private :StringValue
89   ##
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).
93   #--
94   # If we can, we should probably get rid of this.
96   def FloatValue(obj)
97     begin
98       Float(obj)
99     rescue
100       raise TypeError, 'no implicit conversion to float'
101     end
102   end
103   private :FloatValue
105   ##
106   #--
107   # HACK :: added due to broken constant lookup rules
108   #++
110   def raise(exc=Undefined, msg=nil, trace=nil)
111     skip = false
112     if exc.equal? Undefined
113       exc = $!
114       if exc
115         skip = true
116       else
117         exc = RuntimeError.new("No current exception")
118       end
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
125     else
126       raise ::TypeError, 'exception class/object expected'
127     end
129     if $DEBUG and $VERBOSE != nil
130       sender = MethodContext.current.sender
131       STDERR.puts "Exception: `#{exc.class}' #{sender.location} - #{exc.message}"
132     end
134     unless skip
135       exc.context = MethodContext.current.sender unless exc.context
136     end
137     Rubinius.asm(exc) { |e| e.bytecode(self); raise_exc }
138   end
139   module_function :raise
141   alias_method :fail, :raise
142   module_function :fail
144   def warn(warning)
145     $stderr.write "#{warning}\n" unless $VERBOSE.nil?
146     nil
147   end
148   module_function :warn
150   def exit(code=0)
151     code = 0 if code.equal? true
152     raise SystemExit.new(code)
153   end
154   module_function :exit
156   def exit!(code=0)
157     Process.exit(code)
158   end
159   module_function :exit!
161   def abort(msg=nil)
162     Process.abort(msg)
163   end
164   module_function :abort
166   def printf(target, *args)
167     if target.kind_of? IO
168       target.printf(*args)
169     elsif target.kind_of? String
170       $stdout << Sprintf.new(target, *args).parse
171     else
172       raise TypeError, "The first arg to printf should be an IO or a String"
173     end
174     nil
175   end
176   module_function :printf
178   def sprintf(str, *args)
179     Sprintf.new(str, *args).parse
180   end
181   alias_method :format, :sprintf
182   module_function :sprintf
183   module_function :format
184   module_function :abort
186   def puts(*a)
187     $stdout.puts(*a)
188     return nil
189   end
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.
195   def p(*a)
196     return nil if a.empty?
197     a.each { |obj| $stdout.puts obj.inspect }
198     nil
199   end
200   module_function :p
202   def print(*args)
203     args.each do |obj|
204       $stdout.write obj.to_s
205     end
206     nil
207   end
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)
215     end
217     File.open(path, *rest, &block)
218   end
219   module_function :open
221   #--
222   # NOTE: This isn't quite MRI compatible.
223   # We don't seed the RNG by default with a combination of time, pid and
224   # sequence number
225   #++
227   def srand(seed)
228     cur = Kernel.current_srand
229     Platform::POSIX.srand(seed.to_i)
230     Kernel.current_srand = seed.to_i
231     return cur
232   end
233   module_function :srand
235   @current_seed = 0
236   def self.current_srand
237     @current_seed
238   end
240   def self.current_srand=(val)
241     @current_seed = val
242   end
244   def rand(max=nil)
245     max = max.to_i.abs
246     x = Platform::POSIX.rand
247     # scale result of rand to a domain between 0 and max
248     if max.zero?
249       x / 0x7fffffff.to_f
250     else
251       if max < 0x7fffffff
252         x / (0x7fffffff / max)
253       else
254          x * (max / 0x7fffffff)
255       end
256     end
257   end
258   module_function :rand
260   def endian?(order)
261     order == Rubinius::ENDIAN
262   end
263   module_function :endian?
265   def block_given?
266     if MethodContext.current.sender.block
267       return true
268     end
270     return false
271   end
272   module_function :block_given?
274   alias_method :iterator?, :block_given?
275   module_function :iterator?
277   def lambda
278     block = block_given?
279     raise ArgumentError, "block required" if block.nil?
281     block.disable_long_return!
283     return Proc::Function.__from_block__(block)
284   end
285   alias_method :proc, :lambda
286   module_function :lambda
287   module_function :proc
289   def caller(start=1)
290     frame = MethodContext.current.sender
291     frame.stack_trace_starting_at(start)
292   end
293   module_function :caller
295   def global_variables
296     Globals.variables.map { |i| i.to_s }
297   end
298   module_function :global_variables
300   def loop
301     raise LocalJumpError, "no block given" unless block_given?
303     while true
304       yield
305     end
306   end
307   module_function :loop
309   ##
310   # Sleeps the current thread for +duration+ seconds.
312   def sleep(duration = Undefined)
313     start = Time.now
314     chan = Channel.new
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)
322     end
323     chan.receive
324     return (Time.now - start).round
325   end
326   module_function :sleep
328   def at_exit(&block)
329     Rubinius::AtExit.unshift(block)
330   end
331   module_function :at_exit
333   def test(cmd, file1, file2=nil)
334     case cmd
335     when ?d
336       File.directory? file1
337     when ?e
338       File.exist? file1
339     when ?f
340       File.file? file1
341     else
342       false
343     end
344   end
345   module_function :test
347   def trap(sig, prc=nil, &block)
348     Signal.trap(sig, prc, &block)
349   end
350   module_function :trap
352   def initialize_copy(other)
353     return self
354   end
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:
367   #
368   #   case obj
369   #   when /Foo/
370   #     ...
371   #   when "Hi"
372   #     ...
373   #   end
374   #
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.
379   #
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.
386   def ===(other)
387     equal?(other) || self == other
388   end
390   ##
391   # Regexp matching fails by default but may be overridden by subclasses,
392   # notably Regexp and String.
394   def =~(other)
395     false
396   end
398   def class_variable_get(sym)
399     self.class.class_variable_get sym
400   end
402   def class_variable_set(sym, value)
403     self.class.class_variable_set sym, value
404   end
406   def class_variables(symbols = false)
407     self.class.class_variables(symbols)
408   end
410   ##
411   # \_\_const_set__ is emitted by the compiler for const assignment
412   # in userland.
413   #
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"
418   end
420   ##
421   # Activates the singleton Debugger instance, and sets a breakpoint
422   # immediately after the call site to this method.
423   #--
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
426   # breakpoint is hit.
428   def debugger
429     require 'debugger/debugger'
430     dbg = Debugger.instance
432     unless dbg.interface
433       # Default to command-line interface if nothing registered
434       require 'debugger/interface'
435       Debugger::CmdLineInterface.new
436     end
438     ctxt = MethodContext.current.sender
439     cm = ctxt.method
440     ip = ctxt.ip
441     bp = dbg.get_breakpoint(cm, ip)
442     if bp
443       bp.enable unless bp.enabled?
444     else
445       bp = dbg.set_breakpoint(cm, ip)
446     end
448     # Modify send site not to call this method again
449     bc = ctxt.method.bytecodes
450     
451     Breakpoint.encoder.replace_instruction(bc, ip-4, [:noop])
452     Breakpoint.encoder.replace_instruction(bc, ip-2, [:noop])
454     ctxt.reload_method
455   end
457   alias_method :breakpoint, :debugger
459   alias_method :eql?, :equal?
461   def extend(*modules)
462     modules.reverse_each do |mod|
463       mod.extend_object(self)
464       mod.send(:extended, self)
465     end
466     self
467   end
469   def inspect(prefix=nil, vars=nil)
470     return "..." if RecursionGuard.inspecting?(self)
472     iv = __ivars__()
474     return self.to_s unless iv
476     if (iv.is_a?(Hash) or iv.is_a?(Tuple)) and iv.empty?
477       return self.to_s
478     end
480     prefix = "#{self.class}:0x#{self.object_id.to_s(16)}" unless prefix
481     parts = []
483     RecursionGuard.inspect(self) do
485       if iv.is_a?(Hash)
486         iv.each do |k,v|
487           next if vars and !vars.include?(k)
488           parts << "#{k}=#{v.inspect}"
489         end
490       else
491         0.step(iv.size - 1, 2) do |i|
492           if k = iv[i]
493             next if vars and !vars.include?(k)
494             v = iv[i+1]
495             parts << "#{k}=#{v.inspect}"
496           end
497         end
498       end
500     end
502     if parts.empty?
503       "#<#{prefix}>"
504     else
505       "#<#{prefix} #{parts.join(' ')}>"
506     end
507   end
509   ##
510   # :call-seq:
511   #   obj.instance_exec(arg, ...) { |var,...| block }  => obj
512   #
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.
516   #
517   # Arguments are passed as block parameters.
518   #
519   #   class Klass
520   #     def initialize
521   #       @secret = 99
522   #     end
523   #   end
524   #   
525   #   k = Klass.new
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)
532     env.call(*args)
533   end
535   ##
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.
538   #
539   # Module objects can also be given for MRI compatibility but the result is
540   # always false.
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"
546     end
548     self.class == cls
549   end
551   def instance_variable_get(sym)
552     sym = instance_variable_validate(sym)
553     get_instance_variable(sym)
554   end
556   def instance_variable_set(sym, value)
557     sym = instance_variable_validate(sym)
558     set_instance_variable(sym, value)
559   end
561   def remove_instance_variable(sym)
562     # HACK
563     instance_variable_set(sym, nil)
564   end
565   private :remove_instance_variable
567   def instance_variables
568     vars = get_instance_variables
569     return [] if vars.nil?
571     # CSM awareness
572     if vars.kind_of? Tuple
573       out = []
574       0.step(vars.size - 1, 2) do |i|
575         k = vars[i]
576         if k
577           k = k.to_s
578           out << k
579         else
580           return out
581         end
582       end
583       return out
584     end
585     return vars.keys.collect { |v| v.to_s }
586   end
588   def instance_variable_defined?(name)
589     name = instance_variable_validate(name)
591     vars = get_instance_variables
592     return false unless vars
594     # CSM awareness
595     if vars.kind_of? Tuple
596       out = []
597       0.step(vars.size - 1, 2) do |i|
598         k = vars[i]
599         return true if k == name
600       end
602       return false
603     end
605     return vars.key?(name)
606   end
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)
614   end
615   private :singleton_method_added
617   def singleton_method_removed(name)
618   end
619   private :singleton_method_removed
621   def singleton_method_undefined(name)
622   end
623   private :singleton_method_undefined
625   alias_method :is_a?, :kind_of?
627   def method(name)
628     cm = __find_method__(name)
630     if cm
631       return Method.new(self, cm[1], cm[0])
632     else
633       raise NameError, "undefined method `#{name}' for #{self.inspect}"
634     end
635   end
637   def nil?
638     false
639   end
641   def method_missing_cv(meth, *args)
642     # Exclude method_missing from the backtrace since it only confuses
643     # people.
644     myself = MethodContext.current
645     ctx = myself.sender
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)
651     else
652       raise NoMethodError.new("No method '#{meth}' on an instance of #{self.__class__}.", ctx, args)
653     end
654   end
656   private :method_missing_cv
658   def methods(all=true)
659     names = singleton_methods(all)
660     names |= self.class.instance_methods(true) if all
661     return names
662   end
664   def private_methods(all=true)
665     names = private_singleton_methods
666     names |= self.class.private_instance_methods(all)
667     return names
668   end
670   def private_singleton_methods
671     metaclass.method_table.private_names.map { |meth| meth.to_s }
672   end
674   def protected_methods(all=true)
675     names = protected_singleton_methods
676     names |= self.class.protected_instance_methods(all)
677     return names
678   end
680   def protected_singleton_methods
681     metaclass.method_table.protected_names.map { |meth| meth.to_s }
682   end
684   def public_methods(all=true)
685     names = singleton_methods(all)
686     names |= self.class.public_instance_methods(all)
687     return names
688   end
690   def singleton_methods(all=true)
691     mt = metaclass.method_table
692     if all
693       return mt.keys.map { |m| m.to_s }
694     else
695       (mt.public_names + mt.protected_names).map { |m| m.to_s }
696     end
697   end
699   alias_method :send, :__send__
701   def to_a
702     if self.kind_of? Array
703       self
704     else
705       [self]
706     end
707   end
709   def to_s
710     "#<#{self.__class__}:0x#{self.__id__.to_s(16)}>"
711   end
713   def autoload(name, file)
714     Object.autoload(name, file)
715   end
716   private :autoload
718   def autoload?(name)
719     Object.autoload?(name)
720   end
721   private :autoload?
723   def set_trace_func(*args)
724     raise NotImplementedError
725   end
726   module_function :set_trace_func
727   
728   def syscall(*args)
729     raise NotImplementedError
730   end
731   module_function :syscall
733   def trace_var(*args)
734     raise NotImplementedError
735   end
736   module_function :trace_var
738   def untrace_var(*args)
739     raise NotImplementedError
740   end
741   module_function :untrace_var
743   # Perlisms.
745   def chomp(string=$/)
746     ensure_last_read_string
747     $_ = $_.chomp(string)
748   end
749   module_function :chomp
750   
751   def chomp!(string=$/)
752     ensure_last_read_string
753     $_.chomp!(string)
754   end
755   module_function :chomp!
757   def chop(string=$/)
758     ensure_last_read_string
759     $_ = $_.chop(string)
760   end
761   module_function :chop
762   
763   def chop!(string=$/)
764     ensure_last_read_string
765     $_.chop!(string)
766   end
767   module_function :chop!
769   def getc
770     $stdin.getc
771   end
772   module_function :getc
774   def putc(int)
775     $stdin.putc(int)
776   end
777   module_function :putc
779   def gets(sep=$/)
780     # HACK. Needs to use ARGF first.
781     $stdin.gets(sep)
782   end
783   module_function :gets
785   def readline(sep)
786     $stdin.readline(sep)
787   end
788   module_function :readline
789   
790   def readlines(sep)
791     $stdin.readlines(sep)
792   end
793   module_function :readlines
795   def gsub(pattern, rep=nil, &block)
796     ensure_last_read_string
797     $_ = $_.gsub(pattern, rep, &block)
798   end
799   module_function :gsub
800   
801   def gsub!(pattern, rep=nil, &block)
802     ensure_last_read_string
803     $_.gsub!(pattern, rep, &block)
804   end
805   module_function :gsub!
807   def sub(pattern, rep=nil, &block)
808     ensure_last_read_string
809     $_ = $_.sub(pattern, rep, &block)
810   end
811   module_function :sub
812   
813   def sub!(pattern, rep=nil, &block)
814     ensure_last_read_string
815     $_.sub!(pattern, rep, &block)
816   end
817   module_function :sub!
819   def scan(pattern, &block)
820     ensure_last_read_string
821     $_.scan(pattern, &block)
822   end
823   module_function :scan
825   def select(*args)
826     IO.select(*args)
827   end
828   module_function :select
830   def split(*args)
831     ensure_last_read_string
832     $_.split(*args)
833   end
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)"
842     end
843   end
844   module_function :ensure_last_read_string
845   private :ensure_last_read_string
847   # From bootstrap
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.
857     get = proc { $! }
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)
865     get = proc { ARGV }
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)
873   end
877 class SystemExit < Exception
878   def initialize(status)
879     @status = status
880   end
882   attr_reader :status
884   def message
885     "System is exiting with code '#{status}'"
886   end