module Kernel def equal?(other) Rubinius.primitive :object_equal raise PrimitiveFailure, "Kernel#equal? primitive failed" end alias_method :eql?, :equal? alias_method :==, :equal? alias_method :===, :equal? def !~(other) res = self =~ other ? false : true Regexp.last_match = Regexp.last_match res end def become(other) Rubinius.primitive :object_become raise PrimitiveFailure, "Object#become primitive failed" end def singleton_class Rubinius::Type.object_singleton_class self end def extend(mod) Rubinius::Type.object_singleton_class(self).include(mod) self end def freeze Rubinius.primitive :object_freeze raise PrimitiveFailure, "Kernel#freeze primitive failed" end def frozen? Rubinius.primitive :object_frozen_p raise PrimitiveFailure, "Kernel#frozen? primitive failed" end def hash Rubinius.primitive :object_hash raise PrimitiveFailure, "Kernel#hash primitive failed" end def inspect "#<#{self.class.name}" end def respond_to_prim?(meth, visibility) Rubinius.primitive :object_respond_to meth = Rubinius::Type.coerce_to_symbol meth respond_to_prim?(meth, visibility) end private :respond_to_prim? def taint Rubinius.primitive :object_taint raise PrimitiveFailure, "Kernel#taint primitive failed" end def tainted? Rubinius.primitive :object_tainted_p raise PrimitiveFailure, "Kernel#tainted? primitive failed" end def untaint Rubinius.primitive :object_untaint raise PrimitiveFailure, "Kernel#untaint primitive failed" end alias_method :untrust, :taint alias_method :trust, :untaint alias_method :untrusted?, :tainted? # NOTE: The bootstrap method used to add method definitions to the class # method_table still returns a CompiledCode instance, so this chaining # works. # # TODO: Fix this chaining by introducing a proper facility to operate on # methods. def respond_to?(meth, include_private=false) respond_to_prim?(meth, include_private) end custom_call_site :respond_to? def respond_to_missing?(meth, include_private) false end private :respond_to_missing? def yield_gdb(obj) Rubinius.primitive :yield_gdb raise PrimitiveFailure, "Kernel#yield_gdb primitive failed" end private :yield_gdb def Array(obj) ary = Rubinius::Type.check_convert_type obj, Array, :to_ary return ary if ary if array = Rubinius::Type.check_convert_type(obj, Array, :to_a) array else [obj] end end module_function :Array def Complex(*args) Rubinius.privately do Complex.convert(*args) end end module_function :Complex def Float(obj) case obj when String Rubinius::Type.coerce_string_to_float obj, true else Rubinius::Type.coerce_object_to_float obj end end module_function :Float ## # MRI uses a macro named NUM2DBL which has essentially the same semantics as # Float(), with the difference that it raises a TypeError and not a # ArgumentError. It is only used in a few places (in MRI and Rubinius). #-- # If we can, we should probably get rid of this. def FloatValue(obj) exception = TypeError.new 'no implicit conversion to float' case obj when String raise exception else begin Rubinius::Type.coerce_object_to_float obj rescue raise exception end end end private :FloatValue def Hash(obj) return {} if obj.nil? || obj == [] if hash = Rubinius::Type.check_convert_type(obj, Hash, :to_hash) return hash end raise TypeError, "can't convert #{obj.class} into Hash" end module_function :Hash def Integer(obj, base=nil) if obj.kind_of? String if obj.empty? raise ArgumentError, "invalid value for Integer: (empty string)" else base ||= 0 return obj.to_inum(base, true) end end if base raise ArgumentError, "base is only valid for String values" end case obj when Integer obj when Float if obj.nan? or obj.infinite? raise FloatDomainError, "unable to coerce #{obj} to Integer" else obj.to_int end when NilClass raise TypeError, "can't convert nil into Integer" else # Can't use coerce_to or try_convert because I think there is an # MRI bug here where it will return the value without checking # the return type. if obj.respond_to? :to_int if val = obj.to_int return val end end Rubinius::Type.coerce_to obj, Integer, :to_i end end module_function :Integer def Rational(a, b = 1) Rubinius.privately do Rational.convert a, b end end module_function :Rational def String(obj) return obj if obj.kind_of? String unless obj.respond_to?(:to_s) raise TypeError, "can't convert #{obj.class} into String" end begin str = obj.to_s rescue NoMethodError raise TypeError, "can't convert #{obj.class} into String" end unless str.kind_of? String raise TypeError, "#to_s did not return a String" end return str end module_function :String ## # MRI uses a macro named StringValue which has essentially the same # semantics as obj.coerce_to(String, :to_str), but rather than using that # long construction everywhere, we define a private method similar to # String(). # # Another possibility would be to change String() as follows: # # String(obj, sym=:to_s) # # and use String(obj, :to_str) instead of StringValue(obj) def StringValue(obj) Rubinius::Type.coerce_to obj, String, :to_str end module_function :StringValue def __method__ scope = Rubinius::VariableScope.of_sender return nil if scope.method.for_module_body? name = scope.method.name # If the name is still __block__, then it's in a script, so return nil return nil if name == :__block__ or name == :__script__ name end module_function :__method__ def __callee__ scope = Rubinius::VariableScope.of_sender return nil if scope.method.for_module_body? name = scope.name # If the name is still __block__, then it's in a script, so return nil return nil if name == :__block__ or name == :__script__ name end module_function :__callee__ def __dir__ scope = Rubinius::LexicalScope.of_sender script = scope.current_script basepath = script.file_path fullpath = nil return nil unless basepath fullpath = if script.data_path script.data_path else Rubinius.privately do File.basic_realpath(basepath) end end File.dirname fullpath end module_function :__dir__ def `(str) #` str = StringValue(str) unless str.kind_of?(String) pid, output = Rubinius::Mirror::Process.backtick str Process.waitpid(pid) Rubinius::Type.external_string output end module_function :` # ` def =~(other) nil end def <=>(other) self == other ? 0 : nil end def ===(other) equal?(other) || self == other end def itself self end def abort(msg=nil) Process.abort msg end module_function :abort def at_exit(prc=nil, &block) if prc unless prc.respond_to?(:call) raise "Argument must respond to #call" end else prc = block end unless prc raise "must pass a #call'able or block" end Rubinius::AtExit.unshift(prc) end module_function :at_exit def autoload(name, file) Object.autoload(name, file) end private :autoload def autoload?(name) Object.autoload?(name) end private :autoload? def block_given? Rubinius::VariableScope.of_sender.block != nil end module_function :block_given? alias_method :iterator?, :block_given? module_function :iterator? def caller_inner(start, length) if start.is_a?(Range) length = start.size start = start.begin end # The + 2 is to skip this frame and the caller's. # # TODO: plumb length into mri_backtrace to save some work. full_trace = Rubinius.mri_backtrace(start + 2) if length full_trace = full_trace.slice(0, length) end full_trace end module_function :caller_inner private :caller_inner def caller(start = 1, length = nil) caller_inner(start, length).map do |tup| code = tup[0] line = tup[1] is_block = tup[2] name = tup[3] "#{code.active_path}:#{line}:in `#{name}'" end end module_function :caller ## # Returns the current call stack as an Array of Thread::Backtrace::Location # instances. This method is available starting with Ruby 2.0. # def caller_locations(start = 1, length = nil) caller_inner(start, length).map do |tup| scope = tup[0].scope abs_path = tup[0].active_path path = scope ? scope.active_path : abs_path label = tup[3].to_s Thread::Backtrace::Location.new(label, abs_path, path, tup[1]) end end module_function :caller_locations def define_singleton_method(*args, &block) singleton_class.send(:define_method, *args, &block) end def display(port=$>) port.write self end def exec(*args) Process.exec(*args) end module_function :exec def exit(code=0) Process.exit(code) end module_function :exit def exit!(code=1) Process.exit!(code) end module_function :exit! def fork(&block) Process.fork(&block) end module_function :fork def getc $stdin.getc end module_function :getc def gets(sep=$/) ARGF.gets(sep) end module_function :gets def global_variables Rubinius::Globals.variables end module_function :global_variables def initialize_dup(other) initialize_copy(other) end private :initialize_dup def initialize_clone(other) initialize_copy(other) end private :initialize_clone def initialize_copy(source) unless instance_of?(Rubinius::Type.object_class(source)) raise TypeError, "initialize_copy should take same class object" end end private :initialize_copy def inspect prefix = "#<#{self.class}:0x#{self.__id__.to_s(16)}" # The protocol here seems odd, but it's to match MRI. # # MRI side-calls to the C function that implements Kernel#to_s. If that # method is overridden, the new Ruby method is never called. So, we inline # the code for Kernel#to_s here because we simply dispatch to Ruby # methods. ivars = Rubinius.invoke_primitive :object_instance_variables, self if ivars.empty? return Rubinius::Type.infect "#{prefix}>", self end # Otherwise, if it's already been inspected, return the ... return "#{prefix} ...>" if Thread.guarding? self # Otherwise, gather the ivars and show them. parts = [] Thread.recursion_guard self do ivars.each do |var| parts << "#{var}=#{__instance_variable_get__(var).inspect}" end end if parts.empty? str = "#{prefix}>" else str = "#{prefix} #{parts.join(' ')}>" end Rubinius::Type.infect(str, self) return str end ## # Returns true if this object is an instance of the given class, otherwise # false. Raises a TypeError if a non-Class object given. # # Module objects can also be given for MRI compatibility but the result is # always false. def instance_of?(cls) Rubinius.primitive :object_instance_of arg_class = Rubinius::Type.object_class(cls) if arg_class != Class and arg_class != Module # We can obviously compare against Modules but result is always false raise TypeError, "instance_of? requires a Class argument" end Rubinius::Type.object_class(self) == cls end def instance_variable_get(sym) Rubinius.primitive :object_get_ivar sym = Rubinius::Type.ivar_validate sym instance_variable_get sym end alias_method :__instance_variable_get__, :instance_variable_get def instance_variable_set(sym, value) Rubinius.primitive :object_set_ivar sym = Rubinius::Type.ivar_validate sym instance_variable_set sym, value end alias_method :__instance_variable_set__, :instance_variable_set def instance_variables Rubinius.invoke_primitive :object_instance_variables, self end def instance_variable_defined?(name) Rubinius.primitive :object_ivar_defined instance_variable_defined? Rubinius::Type.ivar_validate(name) end # Both of these are for defined? when used inside a proxy obj that # may undef the regular method. The compiler generates __ calls. alias_method :__instance_variable_defined_p__, :instance_variable_defined? alias_method :__respond_to_p__, :respond_to? alias_method :is_a?, :kind_of? def lambda env = nil Rubinius.asm do push_block # assign a pushed block to the above local variable "env" # Note that "env" is indexed at 0. set_local 0 end raise ArgumentError, "block required" unless env prc = Rubinius::Mirror::Proc.from_block ::Proc, env # Make a proc lambda only when passed an actual block (ie, not using the # "&block" notation), otherwise don't modify it at all. prc.lambda_style! if env.is_a?(Rubinius::BlockEnvironment) return prc end module_function :lambda def load(name, wrap=false) Rubinius::CodeLoader.new(name).load(wrap) # cl = Rubinius::CodeLoader.new(name) # cl.load(wrap) # Rubinius.run_script cl.compiled_code # Rubinius::CodeLoader.loaded_hook.trigger!(name) # return true end module_function :load def loop return to_enum(:loop) { Float::INFINITY } unless block_given? begin while true yield end rescue StopIteration => e e.result end end module_function :loop def method(name) name = Rubinius::Type.coerce_to_symbol name code = Rubinius.find_method(self, name) if code Method.new(self, code[1], code[0], name) elsif respond_to_missing?(name, true) Method.new(self, self.class, Rubinius::MissingMethod.new(self, name), name) else raise NameError, "undefined method `#{name}' for class #{self.class}" end end def methods(all=true) methods = singleton_methods(all) if all # We have to special case these because unlike true, false, nil, # Type.object_singleton_class raises a TypeError. case self when Fixnum, Symbol methods |= Rubinius::Type.object_class(self).instance_methods(true) else methods |= Rubinius::Type.object_singleton_class(self).instance_methods(true) end end return methods if kind_of?(ImmediateValue) undefs = [] Rubinius::Type.object_singleton_class(self).method_table.filter_entries do |entry| undefs << entry.name.to_s if entry.visibility == :undef end return methods - undefs end def object_id Rubinius.primitive :object_id raise PrimitiveFailure, "Kernel#object_id primitive failed" end def open(obj, *rest, &block) if obj.respond_to?(:to_open) obj = obj.to_open(*rest) if block_given? return yield(obj) else return obj end end path = Rubinius::Type.coerce_to_path obj if path.kind_of? String and path.prefix? '|' return IO.popen(path[1..-1], *rest, &block) end File.open(path, *rest, &block) end module_function :open def p(*a) return nil if a.empty? a.each { |obj| $stdout.puts obj.inspect } $stdout.flush a.size == 1 ? a.first : a end module_function :p def print(*args) args.each do |obj| $stdout.write obj.to_s end nil end module_function :print def printf(target, *args) if target.kind_of?(String) output = $stdout else output = target target = args.shift end output.write Rubinius::Sprinter.get(target).call(*args) nil end module_function :printf def private_methods(all=true) private_singleton_methods() | Rubinius::Type.object_class(self).private_instance_methods(all) end def private_singleton_methods sc = Rubinius::Type.object_singleton_class self methods = sc.method_table.private_names m = sc while m = m.direct_superclass unless Rubinius::Type.object_kind_of?(m, Rubinius::IncludedModule) or Rubinius::Type.singleton_class_object(m) break end methods.concat m.method_table.private_names end methods end private :private_singleton_methods def proc env = nil Rubinius.asm do push_block # assign a pushed block to the above local variable "env" set_local 0 end unless env # Support for ancient pre-block-pass style: # def something # proc # end # something { a_block } => Proc instance env = Rubinius::BlockEnvironment.of_sender unless env raise ArgumentError, "tried to create a Proc object without a block" end end Proc.new(&env) end module_function :proc def protected_methods(all=true) protected_singleton_methods() | Rubinius::Type.object_class(self).protected_instance_methods(all) end def protected_singleton_methods m = Rubinius::Type.object_singleton_class self methods = m.method_table.protected_names while m = m.direct_superclass unless Rubinius::Type.object_kind_of?(m, Rubinius::IncludedModule) or Rubinius::Type.singleton_class_object(m) break end methods.concat m.method_table.protected_names end methods end private :protected_singleton_methods def public_method(name) name = Rubinius::Type.coerce_to_symbol name code = Rubinius.find_public_method(self, name) if code Method.new(self, code[1], code[0], name) elsif respond_to_missing?(name, false) Method.new(self, self.class, Rubinius::MissingMethod.new(self, name), name) else raise NameError, "undefined method `#{name}' for #{self.inspect}" end end def public_methods(all=true) public_singleton_methods | Rubinius::Type.object_class(self).public_instance_methods(all) end def public_send(message, *args) Rubinius.primitive :object_public_send raise PrimitiveFailure, "Kernel#public_send primitive failed" end def public_singleton_methods m = Rubinius::Type.object_singleton_class self methods = m.method_table.public_names while m = m.direct_superclass unless Rubinius::Type.object_kind_of?(m, Rubinius::IncludedModule) or Rubinius::Type.singleton_class_object(m) break end methods.concat m.method_table.public_names end methods end private :public_singleton_methods def putc(int) $stdout.putc(int) end module_function :putc def puts(*a) $stdout.puts(*a) nil end module_function :puts def rand(limit=0) if limit == 0 return Thread.current.randomizer.random_float end if limit.kind_of?(Range) return Thread.current.randomizer.random(limit) else limit = Integer(limit).abs if limit == 0 Thread.current.randomizer.random_float else Thread.current.randomizer.random_integer(limit - 1) end end end module_function :rand def readline(sep=$/) ARGF.readline(sep) end module_function :readline def readlines(sep=$/) ARGF.readlines(sep) end module_function :readlines def remove_instance_variable(sym) Rubinius.primitive :object_del_ivar # If it's already a symbol, then we're here because it doesn't exist. if sym.kind_of? Symbol raise NameError, "instance variable '#{sym}' not defined" end # Otherwise because sym isn't a symbol, coerce it and try again. remove_instance_variable Rubinius::Type.ivar_validate(sym) end def require(name) Rubinius::CodeLoader.new(name).require end module_function :require def require_relative(name) scope = Rubinius::LexicalScope.of_sender Rubinius::CodeLoader.new(name).require_relative(scope) end module_function :require_relative def select(*args) IO.select(*args) end module_function :select def send(message, *args) Rubinius.primitive :object_send raise PrimitiveFailure, "Kernel#send primitive failed" end def set_trace_func(*args) raise NotImplementedError end module_function :set_trace_func def sprintf(str, *args) Rubinius::Sprinter.get(str).call(*args) end module_function :sprintf alias_method :format, :sprintf module_function :format def sleep(duration=undefined) unless undefined.equal? duration if duration.kind_of? Numeric duration = Rubinius::Type.coerce_to duration, Float, :to_f else raise TypeError, 'time interval must be a numeric value' end end Rubinius.invoke_primitive :thread_suspend, Thread.current, duration end module_function :sleep def srand(seed=undefined) if undefined.equal? seed seed = Thread.current.randomizer.generate_seed end seed = Rubinius::Type.coerce_to seed, Integer, :to_int Thread.current.randomizer.swap_seed seed end module_function :srand def tap yield self self end def test(cmd, file1, file2=nil) case cmd when ?d File.directory? file1 when ?e File.exist? file1 when ?f File.file? file1 when ?l File.symlink? file1 when ?r File.readable? file1 when ?R File.readable_real? file1 when ?w File.writable? file1 when ?W File.writable_real? file1 when ?A File.atime file1 when ?C File.ctime file1 when ?M File.mtime file1 else raise NotImplementedError, "command ?#{cmd.chr} not implemented" end end module_function :test def to_enum(method=:each, *args, &block) Enumerator.new(self, method, *args).tap do |enum| Rubinius.privately { enum.size = block } if block_given? end end alias_method :enum_for, :to_enum def trap(sig, prc=nil, &block) Signal.trap(sig, prc, &block) end module_function :trap def singleton_method_added(name) end private :singleton_method_added def singleton_method_removed(name) end private :singleton_method_removed def singleton_method_undefined(name) end private :singleton_method_undefined def singleton_methods(all=true) m = Rubinius::Type.object_singleton_class self mt = m.method_table methods = mt.public_names + mt.protected_names if all while m = m.direct_superclass unless Rubinius::Type.object_kind_of?(m, Rubinius::IncludedModule) or Rubinius::Type.singleton_class_object(m) break end mt = m.method_table methods.concat mt.public_names methods.concat mt.protected_names end end methods.uniq end def spawn(*args) Process.spawn(*args) end module_function :spawn def syscall(*args) raise NotImplementedError end module_function :syscall def system(*args) begin pid = Process.spawn(*args) rescue SystemCallError return nil end Process.waitpid pid $?.exitstatus == 0 end module_function :system def trace_var(name, cmd = nil, &block) if !cmd && !block raise( ArgumentError, 'The 2nd argument should be a Proc/String, alternatively use a block' ) end # We have to use a custom proc since set_hook passes in both the variable # name and value. set = proc do |_, value| if cmd.is_a?(String) eval(cmd) # In MRI if one passes both a proc in `cmd` and a block the latter will # be ignored. elsif cmd.is_a?(Proc) cmd.call(value) elsif block block.call(value) end end Rubinius::Globals.set_hook(name, :[], set) end module_function :trace_var # In MRI one can specify a 2nd argument to remove a specific tracer. # Rubinius::Globals however only supports one hook per variable, hence the # 2nd dummy argument. def untrace_var(name, *args) Rubinius::Globals.remove_hook(name) end module_function :untrace_var def warn(*messages) $stderr.puts(*messages) if !$VERBOSE.nil? && !messages.empty? nil end module_function :warn def warning(message) $stderr.puts message if $VERBOSE end module_function :warning def catch(obj = Object.new, &block) raise LocalJumpError unless block_given? Rubinius::ThrownValue.register(obj) do return Rubinius.catch(obj, block) end end module_function :catch def throw(obj, value=nil) unless Rubinius::ThrownValue.available? obj exc = UncaughtThrowError.new "uncaught throw #{obj.inspect}" exc.tag = obj raise exc end Rubinius.throw obj, value end module_function :throw # Names of local variables at point of call (including evaled) # def local_variables scope = Rubinius::VariableScope.of_sender scope.local_variables end module_function :local_variables # Obtain binding here for future evaluation/execution context. # def binding return Binding.setup( Rubinius::VariableScope.of_sender, Rubinius::CompiledCode.of_sender, Rubinius::LexicalScope.of_sender, Rubinius::VariableScope.of_sender.self, Rubinius::Location.of_closest_ruby_method ) end module_function :binding # Evaluate and execute code given in the String. # def eval(string, binding=nil, filename=nil, lineno=nil) string = StringValue(string) filename = StringValue(filename) if filename lineno = Rubinius::Type.coerce_to lineno, Fixnum, :to_i if lineno lineno = 1 if filename && !lineno if binding binding = Rubinius::Type.coerce_to_binding binding filename ||= binding.lexical_scope.active_path else binding = Binding.setup(Rubinius::VariableScope.of_sender, Rubinius::CompiledCode.of_sender, Rubinius::LexicalScope.of_sender, self) filename ||= "(eval)" end lineno ||= binding.line_number existing_scope = binding.lexical_scope binding.lexical_scope = existing_scope.dup c = Rubinius::ToolSets::Runtime::Compiler be = c.construct_block string, binding, filename, lineno result = be.call_on_instance(binding.receiver) binding.lexical_scope = existing_scope result end module_function :eval private :eval end