From 9ff1e787f915539b1980654e3d3d2013ff5c81d2 Mon Sep 17 00:00:00 2001 From: shyouhei Date: Mon, 7 Jul 2008 07:38:25 +0000 Subject: wrong commit; sorry git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/tags/v1_8_6_269@17938 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ruby_1_8_6/object.c | 2804 --------------------------------------------------- 1 file changed, 2804 deletions(-) delete mode 100644 ruby_1_8_6/object.c (limited to 'ruby_1_8_6/object.c') diff --git a/ruby_1_8_6/object.c b/ruby_1_8_6/object.c deleted file mode 100644 index 60df9b3386..0000000000 --- a/ruby_1_8_6/object.c +++ /dev/null @@ -1,2804 +0,0 @@ -/********************************************************************** - - object.c - - - $Author$ - $Date$ - created at: Thu Jul 15 12:01:24 JST 1993 - - Copyright (C) 1993-2003 Yukihiro Matsumoto - Copyright (C) 2000 Network Applied Communication Laboratory, Inc. - Copyright (C) 2000 Information-technology Promotion Agency, Japan - -**********************************************************************/ - -#include "ruby.h" -#include "st.h" -#include "util.h" -#include -#include -#include -#include - -VALUE rb_mKernel; -VALUE rb_cObject; -VALUE rb_cModule; -VALUE rb_cClass; -VALUE rb_cData; - -VALUE rb_cNilClass; -VALUE rb_cTrueClass; -VALUE rb_cFalseClass; -VALUE rb_cSymbol; - -static ID id_eq, id_eql, id_inspect, id_init_copy; - -/* - * call-seq: - * obj === other => true or false - * - * Case Equality---For class Object, effectively the same - * as calling #==, but typically overridden by descendents - * to provide meaningful semantics in case statements. - */ - -VALUE -rb_equal(obj1, obj2) - VALUE obj1, obj2; -{ - VALUE result; - - if (obj1 == obj2) return Qtrue; - result = rb_funcall(obj1, id_eq, 1, obj2); - if (RTEST(result)) return Qtrue; - return Qfalse; -} - -int -rb_eql(obj1, obj2) - VALUE obj1, obj2; -{ - return RTEST(rb_funcall(obj1, id_eql, 1, obj2)); -} - -/* - * call-seq: - * obj == other => true or false - * obj.equal?(other) => true or false - * obj.eql?(other) => true or false - * - * Equality---At the Object level, == returns - * true only if obj and other are the - * same object. Typically, this method is overridden in descendent - * classes to provide class-specific meaning. - * - * Unlike ==, the equal? method should never be - * overridden by subclasses: it is used to determine object identity - * (that is, a.equal?(b) iff a is the same - * object as b). - * - * The eql? method returns true if - obj and anObject have the - * same value. Used by Hash to test members for equality. - * For objects of class Object, eql? is - * synonymous with ==. Subclasses normally continue this - * tradition, but there are exceptions. Numeric types, for - * example, perform type conversion across ==, but not - * across eql?, so: - * - * 1 == 1.0 #=> true - * 1.eql? 1.0 #=> false - */ - -static VALUE -rb_obj_equal(obj1, obj2) - VALUE obj1, obj2; -{ - if (obj1 == obj2) return Qtrue; - return Qfalse; -} - -/* - * call-seq: - * obj.id => fixnum - * - * Soon-to-be deprecated version of Object#object_id. - */ - -VALUE -rb_obj_id_obsolete(obj) - VALUE obj; -{ - rb_warn("Object#id will be deprecated; use Object#object_id"); - return rb_obj_id(obj); -} - -VALUE -rb_class_real(cl) - VALUE cl; -{ - while (FL_TEST(cl, FL_SINGLETON) || TYPE(cl) == T_ICLASS) { - cl = RCLASS(cl)->super; - } - return cl; -} - -/* - * call-seq: - * obj.type => class - * - * Deprecated synonym for Object#class. - */ - -VALUE -rb_obj_type(obj) - VALUE obj; -{ - rb_warn("Object#type is deprecated; use Object#class"); - return rb_class_real(CLASS_OF(obj)); -} - - -/* - * call-seq: - * obj.class => class - * - * Returns the class of obj, now preferred over - * Object#type, as an object's type in Ruby is only - * loosely tied to that object's class. This method must always be - * called with an explicit receiver, as class is also a - * reserved word in Ruby. - * - * 1.class #=> Fixnum - * self.class #=> Object - */ - -VALUE -rb_obj_class(obj) - VALUE obj; -{ - return rb_class_real(CLASS_OF(obj)); -} - -static void -init_copy(dest, obj) - VALUE dest, obj; -{ - if (OBJ_FROZEN(dest)) { - rb_raise(rb_eTypeError, "[bug] frozen object (%s) allocated", rb_obj_classname(dest)); - } - RBASIC(dest)->flags &= ~(T_MASK|FL_EXIVAR); - RBASIC(dest)->flags |= RBASIC(obj)->flags & (T_MASK|FL_EXIVAR|FL_TAINT); - if (FL_TEST(obj, FL_EXIVAR)) { - rb_copy_generic_ivar(dest, obj); - } - rb_gc_copy_finalizer(dest, obj); - switch (TYPE(obj)) { - case T_OBJECT: - case T_CLASS: - case T_MODULE: - if (ROBJECT(dest)->iv_tbl) { - st_free_table(ROBJECT(dest)->iv_tbl); - ROBJECT(dest)->iv_tbl = 0; - } - if (ROBJECT(obj)->iv_tbl) { - ROBJECT(dest)->iv_tbl = st_copy(ROBJECT(obj)->iv_tbl); - } - } - rb_funcall(dest, id_init_copy, 1, obj); -} - -/* - * call-seq: - * obj.clone -> an_object - * - * Produces a shallow copy of obj---the instance variables of - * obj are copied, but not the objects they reference. Copies - * the frozen and tainted state of obj. See also the discussion - * under Object#dup. - * - * class Klass - * attr_accessor :str - * end - * s1 = Klass.new #=> # - * s1.str = "Hello" #=> "Hello" - * s2 = s1.clone #=> # - * s2.str[1,4] = "i" #=> "i" - * s1.inspect #=> "#" - * s2.inspect #=> "#" - * - * This method may have class-specific behavior. If so, that - * behavior will be documented under the #+initialize_copy+ method of - * the class. - */ - -VALUE -rb_obj_clone(obj) - VALUE obj; -{ - VALUE clone; - - if (rb_special_const_p(obj)) { - rb_raise(rb_eTypeError, "can't clone %s", rb_obj_classname(obj)); - } - clone = rb_obj_alloc(rb_obj_class(obj)); - RBASIC(clone)->klass = rb_singleton_class_clone(obj); - RBASIC(clone)->flags = (RBASIC(obj)->flags | FL_TEST(clone, FL_TAINT)) & ~(FL_FREEZE|FL_FINALIZE); - init_copy(clone, obj); - RBASIC(clone)->flags |= RBASIC(obj)->flags & FL_FREEZE; - - return clone; -} - -/* - * call-seq: - * obj.dup -> an_object - * - * Produces a shallow copy of obj---the instance variables of - * obj are copied, but not the objects they reference. - * dup copies the tainted state of obj. See also - * the discussion under Object#clone. In general, - * clone and dup may have different semantics - * in descendent classes. While clone is used to duplicate - * an object, including its internal state, dup typically - * uses the class of the descendent object to create the new instance. - * - * This method may have class-specific behavior. If so, that - * behavior will be documented under the #+initialize_copy+ method of - * the class. - */ - -VALUE -rb_obj_dup(obj) - VALUE obj; -{ - VALUE dup; - - if (rb_special_const_p(obj)) { - rb_raise(rb_eTypeError, "can't dup %s", rb_obj_classname(obj)); - } - dup = rb_obj_alloc(rb_obj_class(obj)); - init_copy(dup, obj); - - return dup; -} - -/* :nodoc: */ -VALUE -rb_obj_init_copy(obj, orig) - VALUE obj, orig; -{ - if (obj == orig) return obj; - rb_check_frozen(obj); - if (TYPE(obj) != TYPE(orig) || rb_obj_class(obj) != rb_obj_class(orig)) { - rb_raise(rb_eTypeError, "initialize_copy should take same class object"); - } - return obj; -} - -/* - * call-seq: - * obj.to_a -> anArray - * - * Returns an array representation of obj. For objects of class - * Object and others that don't explicitly override the - * method, the return value is an array containing self. - * However, this latter behavior will soon be obsolete. - * - * self.to_a #=> -:1: warning: default `to_a' will be obsolete - * "hello".to_a #=> ["hello"] - * Time.new.to_a #=> [39, 54, 8, 9, 4, 2003, 3, 99, true, "CDT"] - */ - - -static VALUE -rb_any_to_a(obj) - VALUE obj; -{ - rb_warn("default `to_a' will be obsolete"); - return rb_ary_new3(1, obj); -} - - -/* - * call-seq: - * obj.to_s => string - * - * Returns a string representing obj. The default - * to_s prints the object's class and an encoding of the - * object id. As a special case, the top-level object that is the - * initial execution context of Ruby programs returns ``main.'' - */ - -VALUE -rb_any_to_s(obj) - VALUE obj; -{ - char *cname = rb_obj_classname(obj); - size_t len; - VALUE str; - - len = strlen(cname)+6+16; - str = rb_str_new(0, len); /* 6:tags 16:addr */ - snprintf(RSTRING(str)->ptr, len+1, "#<%s:0x%lx>", cname, obj); - RSTRING(str)->len = strlen(RSTRING(str)->ptr); - if (OBJ_TAINTED(obj)) OBJ_TAINT(str); - - return str; -} - -VALUE -rb_inspect(obj) - VALUE obj; -{ - return rb_obj_as_string(rb_funcall(obj, id_inspect, 0, 0)); -} - -static int -inspect_i(id, value, str) - ID id; - VALUE value; - VALUE str; -{ - VALUE str2; - char *ivname; - - /* need not to show internal data */ - if (CLASS_OF(value) == 0) return ST_CONTINUE; - if (!rb_is_instance_id(id)) return ST_CONTINUE; - if (RSTRING(str)->ptr[0] == '-') { /* first element */ - RSTRING(str)->ptr[0] = '#'; - rb_str_cat2(str, " "); - } - else { - rb_str_cat2(str, ", "); - } - ivname = rb_id2name(id); - rb_str_cat2(str, ivname); - rb_str_cat2(str, "="); - str2 = rb_inspect(value); - rb_str_append(str, str2); - OBJ_INFECT(str, str2); - - return ST_CONTINUE; -} - -static VALUE -inspect_obj(obj, str) - VALUE obj, str; -{ - st_foreach_safe(ROBJECT(obj)->iv_tbl, inspect_i, str); - rb_str_cat2(str, ">"); - RSTRING(str)->ptr[0] = '#'; - OBJ_INFECT(str, obj); - - return str; -} - -/* - * call-seq: - * obj.inspect => string - * - * Returns a string containing a human-readable representation of - * obj. If not overridden, uses the to_s method to - * generate the string. - * - * [ 1, 2, 3..4, 'five' ].inspect #=> "[1, 2, 3..4, \"five\"]" - * Time.new.inspect #=> "Wed Apr 09 08:54:39 CDT 2003" - */ - - -static VALUE -rb_obj_inspect(obj) - VALUE obj; -{ - if (TYPE(obj) == T_OBJECT - && ROBJECT(obj)->iv_tbl - && ROBJECT(obj)->iv_tbl->num_entries > 0) { - VALUE str; - size_t len; - char *c; - - c = rb_obj_classname(obj); - if (rb_inspecting_p(obj)) { - len = strlen(c)+10+16+1; - str = rb_str_new(0, len); /* 10:tags 16:addr 1:nul */ - snprintf(RSTRING(str)->ptr, len, "#<%s:0x%lx ...>", c, obj); - RSTRING(str)->len = strlen(RSTRING(str)->ptr); - return str; - } - len = strlen(c)+6+16+1; - str = rb_str_new(0, len); /* 6:tags 16:addr 1:nul */ - snprintf(RSTRING(str)->ptr, len, "-<%s:0x%lx", c, obj); - RSTRING(str)->len = strlen(RSTRING(str)->ptr); - return rb_protect_inspect(inspect_obj, obj, str); - } - return rb_funcall(obj, rb_intern("to_s"), 0, 0); -} - - -/* - * call-seq: - * obj.instance_of?(class) => true or false - * - * Returns true if obj is an instance of the given - * class. See also Object#kind_of?. - */ - -VALUE -rb_obj_is_instance_of(obj, c) - VALUE obj, c; -{ - switch (TYPE(c)) { - case T_MODULE: - case T_CLASS: - case T_ICLASS: - break; - default: - rb_raise(rb_eTypeError, "class or module required"); - } - - if (rb_obj_class(obj) == c) return Qtrue; - return Qfalse; -} - - -/* - * call-seq: - * obj.is_a?(class) => true or false - * obj.kind_of?(class) => true or false - * - * Returns true if class is the class of - * obj, or if class is one of the superclasses of - * obj or modules included in obj. - * - * module M; end - * class A - * include M - * end - * class B < A; end - * class C < B; end - * b = B.new - * b.instance_of? A #=> false - * b.instance_of? B #=> true - * b.instance_of? C #=> false - * b.instance_of? M #=> false - * b.kind_of? A #=> true - * b.kind_of? B #=> true - * b.kind_of? C #=> false - * b.kind_of? M #=> true - */ - -VALUE -rb_obj_is_kind_of(obj, c) - VALUE obj, c; -{ - VALUE cl = CLASS_OF(obj); - - switch (TYPE(c)) { - case T_MODULE: - case T_CLASS: - case T_ICLASS: - break; - - default: - rb_raise(rb_eTypeError, "class or module required"); - } - - while (cl) { - if (cl == c || RCLASS(cl)->m_tbl == RCLASS(c)->m_tbl) - return Qtrue; - cl = RCLASS(cl)->super; - } - return Qfalse; -} - - -/* - * Document-method: inherited - * - * call-seq: - * inherited(subclass) - * - * Callback invoked whenever a subclass of the current class is created. - * - * Example: - * - * class Foo - * def self.inherited(subclass) - * puts "New subclass: #{subclass}" - * end - * end - * - * class Bar < Foo - * end - * - * class Baz < Bar - * end - * - * produces: - * - * New subclass: Bar - * New subclass: Baz - */ - -/* - * Document-method: singleton_method_added - * - * call-seq: - * singleton_method_added(symbol) - * - * Invoked as a callback whenever a singleton method is added to the - * receiver. - * - * module Chatty - * def Chatty.singleton_method_added(id) - * puts "Adding #{id.id2name}" - * end - * def self.one() end - * def two() end - * def Chatty.three() end - * end - * - * produces: - * - * Adding singleton_method_added - * Adding one - * Adding three - * - */ - -/* - * Document-method: singleton_method_removed - * - * call-seq: - * singleton_method_removed(symbol) - * - * Invoked as a callback whenever a singleton method is removed from - * the receiver. - * - * module Chatty - * def Chatty.singleton_method_removed(id) - * puts "Removing #{id.id2name}" - * end - * def self.one() end - * def two() end - * def Chatty.three() end - * class <produces: - * - * Removing three - * Removing one - */ - -/* - * Document-method: singleton_method_undefined - * - * call-seq: - * singleton_method_undefined(symbol) - * - * Invoked as a callback whenever a singleton method is undefined in - * the receiver. - * - * module Chatty - * def Chatty.singleton_method_undefined(id) - * puts "Undefining #{id.id2name}" - * end - * def Chatty.one() end - * class << self - * undef_method(:one) - * end - * end - * - * produces: - * - * Undefining one - */ - - -/* - * Document-method: included - * - * call-seq: - * included( othermod ) - * - * Callback invoked whenever the receiver is included in another - * module or class. This should be used in preference to - * Module.append_features if your code wants to perform some - * action when a module is included in another. - * - * module A - * def A.included(mod) - * puts "#{self} included in #{mod}" - * end - * end - * module Enumerable - * include A - * end - */ - - -/* - * Not documented - */ - -static VALUE -rb_obj_dummy() -{ - return Qnil; -} - -/* - * call-seq: - * obj.tainted? => true or false - * - * Returns true if the object is tainted. - */ - -VALUE -rb_obj_tainted(obj) - VALUE obj; -{ - if (OBJ_TAINTED(obj)) - return Qtrue; - return Qfalse; -} - -/* - * call-seq: - * obj.taint -> obj - * - * Marks obj as tainted---if the $SAFE level is - * set appropriately, many method calls which might alter the running - * programs environment will refuse to accept tainted strings. - */ - -VALUE -rb_obj_taint(obj) - VALUE obj; -{ - rb_secure(4); - if (!OBJ_TAINTED(obj)) { - if (OBJ_FROZEN(obj)) { - rb_error_frozen("object"); - } - OBJ_TAINT(obj); - } - return obj; -} - - -/* - * call-seq: - * obj.untaint => obj - * - * Removes the taint from obj. - */ - -VALUE -rb_obj_untaint(obj) - VALUE obj; -{ - rb_secure(3); - if (OBJ_TAINTED(obj)) { - if (OBJ_FROZEN(obj)) { - rb_error_frozen("object"); - } - FL_UNSET(obj, FL_TAINT); - } - return obj; -} - -void -rb_obj_infect(obj1, obj2) - VALUE obj1, obj2; -{ - OBJ_INFECT(obj1, obj2); -} - - -/* - * call-seq: - * obj.freeze => obj - * - * Prevents further modifications to obj. A - * TypeError will be raised if modification is attempted. - * There is no way to unfreeze a frozen object. See also - * Object#frozen?. - * - * a = [ "a", "b", "c" ] - * a.freeze - * a << "z" - * - * produces: - * - * prog.rb:3:in `<<': can't modify frozen array (TypeError) - * from prog.rb:3 - */ - -VALUE -rb_obj_freeze(obj) - VALUE obj; -{ - if (!OBJ_FROZEN(obj)) { - if (rb_safe_level() >= 4 && !OBJ_TAINTED(obj)) { - rb_raise(rb_eSecurityError, "Insecure: can't freeze object"); - } - OBJ_FREEZE(obj); - } - return obj; -} - -/* - * call-seq: - * obj.frozen? => true or false - * - * Returns the freeze status of obj. - * - * a = [ "a", "b", "c" ] - * a.freeze #=> ["a", "b", "c"] - * a.frozen? #=> true - */ - -static VALUE -rb_obj_frozen_p(obj) - VALUE obj; -{ - if (OBJ_FROZEN(obj)) return Qtrue; - return Qfalse; -} - - -/* - * Document-class: NilClass - * - * The class of the singleton object nil. - */ - -/* - * call-seq: - * nil.to_i => 0 - * - * Always returns zero. - * - * nil.to_i #=> 0 - */ - - -static VALUE -nil_to_i(obj) - VALUE obj; -{ - return INT2FIX(0); -} - -/* - * call-seq: - * nil.to_f => 0.0 - * - * Always returns zero. - * - * nil.to_f #=> 0.0 - */ - -static VALUE -nil_to_f(obj) - VALUE obj; -{ - return rb_float_new(0.0); -} - -/* - * call-seq: - * nil.to_s => "" - * - * Always returns the empty string. - * - * nil.to_s #=> "" - */ - -static VALUE -nil_to_s(obj) - VALUE obj; -{ - return rb_str_new2(""); -} - -/* - * call-seq: - * nil.to_a => [] - * - * Always returns an empty array. - * - * nil.to_a #=> [] - */ - -static VALUE -nil_to_a(obj) - VALUE obj; -{ - return rb_ary_new2(0); -} - -/* - * call-seq: - * nil.inspect => "nil" - * - * Always returns the string "nil". - */ - -static VALUE -nil_inspect(obj) - VALUE obj; -{ - return rb_str_new2("nil"); -} - -static VALUE -main_to_s(obj) - VALUE obj; -{ - return rb_str_new2("main"); -} - - -/*********************************************************************** - * Document-class: TrueClass - * - * The global value true is the only instance of class - * TrueClass and represents a logically true value in - * boolean expressions. The class provides operators allowing - * true to be used in logical expressions. - */ - - -/* - * call-seq: - * true.to_s => "true" - * - * The string representation of true is "true". - */ - -static VALUE -true_to_s(obj) - VALUE obj; -{ - return rb_str_new2("true"); -} - - -/* - * call-seq: - * true & obj => true or false - * - * And---Returns false if obj is - * nil or false, true otherwise. - */ - -static VALUE -true_and(obj, obj2) - VALUE obj, obj2; -{ - return RTEST(obj2)?Qtrue:Qfalse; -} - -/* - * call-seq: - * true | obj => true - * - * Or---Returns true. As anObject is an argument to - * a method call, it is always evaluated; there is no short-circuit - * evaluation in this case. - * - * true | puts("or") - * true || puts("logical or") - * - * produces: - * - * or - */ - -static VALUE -true_or(obj, obj2) - VALUE obj, obj2; -{ - return Qtrue; -} - - -/* - * call-seq: - * true ^ obj => !obj - * - * Exclusive Or---Returns true if obj is - * nil or false, false - * otherwise. - */ - -static VALUE -true_xor(obj, obj2) - VALUE obj, obj2; -{ - return RTEST(obj2)?Qfalse:Qtrue; -} - - -/* - * Document-class: FalseClass - * - * The global value false is the only instance of class - * FalseClass and represents a logically false value in - * boolean expressions. The class provides operators allowing - * false to participate correctly in logical expressions. - * - */ - -/* - * call-seq: - * false.to_s => "false" - * - * 'nuf said... - */ - -static VALUE -false_to_s(obj) - VALUE obj; -{ - return rb_str_new2("false"); -} - -/* - * call-seq: - * false & obj => false - * nil & obj => false - * - * And---Returns false. obj is always - * evaluated as it is the argument to a method call---there is no - * short-circuit evaluation in this case. - */ - -static VALUE -false_and(obj, obj2) - VALUE obj, obj2; -{ - return Qfalse; -} - - -/* - * call-seq: - * false | obj => true or false - * nil | obj => true or false - * - * Or---Returns false if obj is - * nil or false; true otherwise. - */ - -static VALUE -false_or(obj, obj2) - VALUE obj, obj2; -{ - return RTEST(obj2)?Qtrue:Qfalse; -} - - - -/* - * call-seq: - * false ^ obj => true or false - * nil ^ obj => true or false - * - * Exclusive Or---If obj is nil or - * false, returns false; otherwise, returns - * true. - * - */ - -static VALUE -false_xor(obj, obj2) - VALUE obj, obj2; -{ - return RTEST(obj2)?Qtrue:Qfalse; -} - -/* - * call_seq: - * nil.nil? => true - * - * Only the object nil responds true to nil?. - */ - -static VALUE -rb_true(obj) - VALUE obj; -{ - return Qtrue; -} - -/* - * call_seq: - * nil.nil? => true - * .nil? => false - * - * Only the object nil responds true to nil?. - */ - - -static VALUE -rb_false(obj) - VALUE obj; -{ - return Qfalse; -} - - -/* - * call-seq: - * obj =~ other => false - * - * Pattern Match---Overridden by descendents (notably - * Regexp and String) to provide meaningful - * pattern-match semantics. - */ - -static VALUE -rb_obj_pattern_match(obj1, obj2) - VALUE obj1, obj2; -{ - return Qfalse; -} - -/********************************************************************** - * Document-class: Symbol - * - * Symbol objects represent names and some strings - * inside the Ruby - * interpreter. They are generated using the :name and - * :"string" literals - * syntax, and by the various to_sym methods. The same - * Symbol object will be created for a given name or string - * for the duration of a program's execution, regardless of the context - * or meaning of that name. Thus if Fred is a constant in - * one context, a method in another, and a class in a third, the - * Symbol :Fred will be the same object in - * all three contexts. - * - * module One - * class Fred - * end - * $f1 = :Fred - * end - * module Two - * Fred = 1 - * $f2 = :Fred - * end - * def Fred() - * end - * $f3 = :Fred - * $f1.id #=> 2514190 - * $f2.id #=> 2514190 - * $f3.id #=> 2514190 - * - */ - -/* - * call-seq: - * sym.to_i => fixnum - * - * Returns an integer that is unique for each symbol within a - * particular execution of a program. - * - * :fred.to_i #=> 9809 - * "fred".to_sym.to_i #=> 9809 - */ - -static VALUE -sym_to_i(sym) - VALUE sym; -{ - ID id = SYM2ID(sym); - - return LONG2FIX(id); -} - - -/* :nodoc: */ - -static VALUE -sym_to_int(sym) - VALUE sym; -{ - rb_warning("treating Symbol as an integer"); - return sym_to_i(sym); -} - - -/* - * call-seq: - * sym.inspect => string - * - * Returns the representation of sym as a symbol literal. - * - * :fred.inspect #=> ":fred" - */ - -static VALUE -sym_inspect(sym) - VALUE sym; -{ - VALUE str; - char *name; - ID id = SYM2ID(sym); - - name = rb_id2name(id); - str = rb_str_new(0, strlen(name)+1); - RSTRING(str)->ptr[0] = ':'; - strcpy(RSTRING(str)->ptr+1, name); - if (!rb_symname_p(name)) { - str = rb_str_dump(str); - strncpy(RSTRING(str)->ptr, ":\"", 2); - } - return str; -} - - -/* - * call-seq: - * sym.id2name => string - * sym.to_s => string - * - * Returns the name or string corresponding to sym. - * - * :fred.id2name #=> "fred" - */ - - -static VALUE -sym_to_s(sym) - VALUE sym; -{ - return rb_str_new2(rb_id2name(SYM2ID(sym))); -} - - -/* - * call-seq: - * sym.to_sym => sym - * - * In general, to_sym returns the Symbol corresponding - * to an object. As sym is already a symbol, self is returned - * in this case. - */ - -static VALUE -sym_to_sym(sym) - VALUE sym; -{ - return sym; -} - - -/*********************************************************************** - * - * Document-class: Module - * - * A Module is a collection of methods and constants. The - * methods in a module may be instance methods or module methods. - * Instance methods appear as methods in a class when the module is - * included, module methods do not. Conversely, module methods may be - * called without creating an encapsulating object, while instance - * methods may not. (See Module#module_function) - * - * In the descriptions that follow, the parameter syml refers - * to a symbol, which is either a quoted string or a - * Symbol (such as :name). - * - * module Mod - * include Math - * CONST = 1 - * def meth - * # ... - * end - * end - * Mod.class #=> Module - * Mod.constants #=> ["E", "PI", "CONST"] - * Mod.instance_methods #=> ["meth"] - * - */ - -/* - * call-seq: - * mod.to_s => string - * - * Return a string representing this module or class. For basic - * classes and modules, this is the name. For singletons, we - * show information on the thing we're attached to as well. - */ - -static VALUE -rb_mod_to_s(klass) - VALUE klass; - -{ - if (FL_TEST(klass, FL_SINGLETON)) { - VALUE s = rb_str_new2("#<"); - VALUE v = rb_iv_get(klass, "__attached__"); - - rb_str_cat2(s, "Class:"); - switch (TYPE(v)) { - case T_CLASS: case T_MODULE: - rb_str_append(s, rb_inspect(v)); - break; - default: - rb_str_append(s, rb_any_to_s(v)); - break; - } - rb_str_cat2(s, ">"); - - return s; - } - return rb_str_dup(rb_class_name(klass)); -} - -/* - * call-seq: - * mod.freeze - * - * Prevents further modifications to mod. - */ - -static VALUE -rb_mod_freeze(mod) - VALUE mod; -{ - rb_mod_to_s(mod); - return rb_obj_freeze(mod); -} - -/* - * call-seq: - * mod === obj => true or false - * - * Case Equality---Returns true if anObject is an - * instance of mod or one of mod's descendents. Of - * limited use for modules, but can be used in case - * statements to classify objects by class. - */ - -static VALUE -rb_mod_eqq(mod, arg) - VALUE mod, arg; -{ - return rb_obj_is_kind_of(arg, mod); -} - -/* - * call-seq: - * mod <= other => true, false, or nil - * - * Returns true if mod is a subclass of other or - * is the same as other. Returns - * nil if there's no relationship between the two. - * (Think of the relationship in terms of the class definition: - * "class Am_tbl == RCLASS(arg)->m_tbl) - return Qtrue; - mod = RBASIC(mod)->klass; - } - while (mod) { - if (RCLASS(mod)->m_tbl == RCLASS(arg)->m_tbl) - return Qtrue; - mod = RCLASS(mod)->super; - } - /* not mod < arg; check if mod > arg */ - while (arg) { - if (RCLASS(arg)->m_tbl == RCLASS(start)->m_tbl) - return Qfalse; - arg = RCLASS(arg)->super; - } - return Qnil; -} - -/* - * call-seq: - * mod < other => true, false, or nil - * - * Returns true if mod is a subclass of other. Returns - * nil if there's no relationship between the two. - * (Think of the relationship in terms of the class definition: - * "class A= other => true, false, or nil - * - * Returns true if mod is an ancestor of other, or the - * two modules are the same. Returns - * nil if there's no relationship between the two. - * (Think of the relationship in terms of the class definition: - * "class AA"). - * - */ - -static VALUE -rb_mod_ge(mod, arg) - VALUE mod, arg; -{ - switch (TYPE(arg)) { - case T_MODULE: - case T_CLASS: - break; - default: - rb_raise(rb_eTypeError, "compared with non class/module"); - } - - return rb_class_inherited_p(arg, mod); -} - -/* - * call-seq: - * mod > other => true, false, or nil - * - * Returns true if mod is an ancestor of other. Returns - * nil if there's no relationship between the two. - * (Think of the relationship in terms of the class definition: - * "class AA"). - * - */ - -static VALUE -rb_mod_gt(mod, arg) - VALUE mod, arg; -{ - if (mod == arg) return Qfalse; - return rb_mod_ge(mod, arg); -} - -/* - * call-seq: - * mod <=> other_mod => -1, 0, +1, or nil - * - * Comparison---Returns -1 if mod includes other_mod, 0 if - * mod is the same as other_mod, and +1 if mod is - * included by other_mod or if mod has no relationship with - * other_mod. Returns nil if other_mod is - * not a module. - */ - -static VALUE -rb_mod_cmp(mod, arg) - VALUE mod, arg; -{ - VALUE cmp; - - if (mod == arg) return INT2FIX(0); - switch (TYPE(arg)) { - case T_MODULE: - case T_CLASS: - break; - default: - return Qnil; - } - - cmp = rb_class_inherited_p(mod, arg); - if (NIL_P(cmp)) return Qnil; - if (cmp) { - return INT2FIX(-1); - } - return INT2FIX(1); -} - -static VALUE rb_module_s_alloc _((VALUE)); -static VALUE -rb_module_s_alloc(klass) - VALUE klass; -{ - VALUE mod = rb_module_new(); - - RBASIC(mod)->klass = klass; - return mod; -} - -static VALUE rb_class_s_alloc _((VALUE)); -static VALUE -rb_class_s_alloc(klass) - VALUE klass; -{ - return rb_class_boot(0); -} - -/* - * call-seq: - * Module.new => mod - * Module.new {|mod| block } => mod - * - * Creates a new anonymous module. If a block is given, it is passed - * the module object, and the block is evaluated in the context of this - * module using module_eval. - * - * Fred = Module.new do - * def meth1 - * "hello" - * end - * def meth2 - * "bye" - * end - * end - * a = "my string" - * a.extend(Fred) #=> "my string" - * a.meth1 #=> "hello" - * a.meth2 #=> "bye" - */ - -static VALUE -rb_mod_initialize(module) - VALUE module; -{ - if (rb_block_given_p()) { - rb_mod_module_eval(0, 0, module); - } - return Qnil; -} - -/* - * call-seq: - * Class.new(super_class=Object) => a_class - * - * Creates a new anonymous (unnamed) class with the given superclass - * (or Object if no parameter is given). You can give a - * class a name by assigning the class object to a constant. - * - */ - -static VALUE -rb_class_initialize(argc, argv, klass) - int argc; - VALUE *argv; - VALUE klass; -{ - VALUE super; - - if (RCLASS(klass)->super != 0) { - rb_raise(rb_eTypeError, "already initialized class"); - } - if (rb_scan_args(argc, argv, "01", &super) == 0) { - super = rb_cObject; - } - else { - rb_check_inheritable(super); - } - RCLASS(klass)->super = super; - rb_make_metaclass(klass, RBASIC(super)->klass); - rb_mod_initialize(klass); - rb_class_inherited(super, klass); - - return klass; -} - -/* - * call-seq: - * class.allocate() => obj - * - * Allocates space for a new object of class's class. The - * returned object must be an instance of class. - * - */ - -VALUE -rb_obj_alloc(klass) - VALUE klass; -{ - VALUE obj; - - if (RCLASS(klass)->super == 0) { - rb_raise(rb_eTypeError, "can't instantiate uninitialized class"); - } - if (FL_TEST(klass, FL_SINGLETON)) { - rb_raise(rb_eTypeError, "can't create instance of virtual class"); - } - obj = rb_funcall(klass, ID_ALLOCATOR, 0, 0); - if (rb_obj_class(obj) != rb_class_real(klass)) { - rb_raise(rb_eTypeError, "wrong instance allocation"); - } - return obj; -} - -static VALUE rb_class_allocate_instance _((VALUE)); -static VALUE -rb_class_allocate_instance(klass) - VALUE klass; -{ - NEWOBJ(obj, struct RObject); - OBJSETUP(obj, klass, T_OBJECT); - return (VALUE)obj; -} - -/* - * call-seq: - * class.new(args, ...) => obj - * - * Calls allocate to create a new object of - * class's class, then invokes that object's - * initialize method, passing it args. - * This is the method that ends up getting called whenever - * an object is constructed using .new. - * - */ - -VALUE -rb_class_new_instance(argc, argv, klass) - int argc; - VALUE *argv; - VALUE klass; -{ - VALUE obj; - - obj = rb_obj_alloc(klass); - rb_obj_call_init(obj, argc, argv); - - return obj; -} - -/* - * call-seq: - * class.superclass -> a_super_class or nil - * - * Returns the superclass of class, or nil. - * - * File.superclass #=> IO - * IO.superclass #=> Object - * Object.superclass #=> nil - * - */ - -static VALUE -rb_class_superclass(klass) - VALUE klass; -{ - VALUE super = RCLASS(klass)->super; - - if (!super) { - rb_raise(rb_eTypeError, "uninitialized class"); - } - if (FL_TEST(klass, FL_SINGLETON)) { - super = RBASIC(klass)->klass; - } - while (TYPE(super) == T_ICLASS) { - super = RCLASS(super)->super; - } - if (!super) { - return Qnil; - } - return super; -} - -static ID -str_to_id(str) - VALUE str; -{ - VALUE sym = rb_str_intern(str); - - return SYM2ID(sym); -} - -ID -rb_to_id(name) - VALUE name; -{ - VALUE tmp; - ID id; - - switch (TYPE(name)) { - case T_STRING: - return str_to_id(name); - case T_FIXNUM: - rb_warn("do not use Fixnums as Symbols"); - id = FIX2LONG(name); - if (!rb_id2name(id)) { - rb_raise(rb_eArgError, "%ld is not a symbol", id); - } - break; - case T_SYMBOL: - id = SYM2ID(name); - break; - default: - tmp = rb_check_string_type(name); - if (!NIL_P(tmp)) { - return str_to_id(tmp); - } - rb_raise(rb_eTypeError, "%s is not a symbol", RSTRING(rb_inspect(name))->ptr); - } - return id; -} - -/* - * call-seq: - * attr(symbol, writable=false) => nil - * - * Defines a named attribute for this module, where the name is - * symbol.id2name, creating an instance variable - * (@name) and a corresponding access method to read it. - * If the optional writable argument is true, also - * creates a method called name= to set the attribute. - * - * module Mod - * attr :size, true - * end - * - * is equivalent to: - * - * module Mod - * def size - * @size - * end - * def size=(val) - * @size = val - * end - * end - */ - -static VALUE -rb_mod_attr(argc, argv, klass) - int argc; - VALUE *argv; - VALUE klass; -{ - VALUE name, pub; - - rb_scan_args(argc, argv, "11", &name, &pub); - rb_attr(klass, rb_to_id(name), 1, RTEST(pub), Qtrue); - return Qnil; -} - -/* - * call-seq: - * attr_reader(symbol, ...) => nil - * - * Creates instance variables and corresponding methods that return the - * value of each instance variable. Equivalent to calling - * ``attr:name'' on each name in turn. - */ - -static VALUE -rb_mod_attr_reader(argc, argv, klass) - int argc; - VALUE *argv; - VALUE klass; -{ - int i; - - for (i=0; i nil - * - * Creates an accessor method to allow assignment to the attribute - * aSymbol.id2name. - */ - -static VALUE -rb_mod_attr_writer(argc, argv, klass) - int argc; - VALUE *argv; - VALUE klass; -{ - int i; - - for (i=0; i nil - * - * Equivalent to calling ``attrsymbol, - * true'' on each symbol in turn. - * - * module Mod - * attr_accessor(:one, :two) - * end - * Mod.instance_methods.sort #=> ["one", "one=", "two", "two="] - */ - -static VALUE -rb_mod_attr_accessor(argc, argv, klass) - int argc; - VALUE *argv; - VALUE klass; -{ - int i; - - for (i=0; i obj - * - * Returns the value of the named constant in mod. - * - * Math.const_get(:PI) #=> 3.14159265358979 - */ - -static VALUE -rb_mod_const_get(mod, name) - VALUE mod, name; -{ - ID id = rb_to_id(name); - - if (!rb_is_const_id(id)) { - rb_name_error(id, "wrong constant name %s", rb_id2name(id)); - } - return rb_const_get(mod, id); -} - -/* - * call-seq: - * mod.const_set(sym, obj) => obj - * - * Sets the named constant to the given object, returning that object. - * Creates a new constant if no constant with the given name previously - * existed. - * - * Math.const_set("HIGH_SCHOOL_PI", 22.0/7.0) #=> 3.14285714285714 - * Math::HIGH_SCHOOL_PI - Math::PI #=> 0.00126448926734968 - */ - -static VALUE -rb_mod_const_set(mod, name, value) - VALUE mod, name, value; -{ - ID id = rb_to_id(name); - - if (!rb_is_const_id(id)) { - rb_name_error(id, "wrong constant name %s", rb_id2name(id)); - } - rb_const_set(mod, id, value); - return value; -} - -/* - * call-seq: - * mod.const_defined?(sym) => true or false - * - * Returns true if a constant with the given name is - * defined by mod. - * - * Math.const_defined? "PI" #=> true - */ - -static VALUE -rb_mod_const_defined(mod, name) - VALUE mod, name; -{ - ID id = rb_to_id(name); - - if (!rb_is_const_id(id)) { - rb_name_error(id, "wrong constant name %s", rb_id2name(id)); - } - return rb_const_defined_at(mod, id); -} - -/* - * call-seq: - * obj.methods => array - * - * Returns a list of the names of methods publicly accessible in - * obj. This will include all the methods accessible in - * obj's ancestors. - * - * class Klass - * def kMethod() - * end - * end - * k = Klass.new - * k.methods[0..9] #=> ["kMethod", "freeze", "nil?", "is_a?", - * "class", "instance_variable_set", - * "methods", "extend", "__send__", "instance_eval"] - * k.methods.length #=> 42 - */ - -static VALUE -rb_obj_methods(argc, argv, obj) - int argc; - VALUE *argv; - VALUE obj; -{ - retry: - if (argc == 0) { - VALUE args[1]; - - args[0] = Qtrue; - return rb_class_instance_methods(1, args, CLASS_OF(obj)); - } - else { - VALUE recur; - - rb_scan_args(argc, argv, "1", &recur); - if (RTEST(recur)) { - argc = 0; - goto retry; - } - return rb_obj_singleton_methods(argc, argv, obj); - } -} - -/* - * call-seq: - * obj.protected_methods(all=true) => array - * - * Returns the list of protected methods accessible to obj. If - * the all parameter is set to false, only those methods - * in the receiver will be listed. - */ - -static VALUE -rb_obj_protected_methods(argc, argv, obj) - int argc; - VALUE *argv; - VALUE obj; -{ - if (argc == 0) { /* hack to stop warning */ - VALUE args[1]; - - args[0] = Qtrue; - return rb_class_protected_instance_methods(1, args, CLASS_OF(obj)); - } - return rb_class_protected_instance_methods(argc, argv, CLASS_OF(obj)); -} - -/* - * call-seq: - * obj.private_methods(all=true) => array - * - * Returns the list of private methods accessible to obj. If - * the all parameter is set to false, only those methods - * in the receiver will be listed. - */ - -static VALUE -rb_obj_private_methods(argc, argv, obj) - int argc; - VALUE *argv; - VALUE obj; -{ - if (argc == 0) { /* hack to stop warning */ - VALUE args[1]; - - args[0] = Qtrue; - return rb_class_private_instance_methods(1, args, CLASS_OF(obj)); - } - return rb_class_private_instance_methods(argc, argv, CLASS_OF(obj)); -} - -/* - * call-seq: - * obj.public_methods(all=true) => array - * - * Returns the list of public methods accessible to obj. If - * the all parameter is set to false, only those methods - * in the receiver will be listed. - */ - -static VALUE -rb_obj_public_methods(argc, argv, obj) - int argc; - VALUE *argv; - VALUE obj; -{ - if (argc == 0) { /* hack to stop warning */ - VALUE args[1]; - - args[0] = Qtrue; - return rb_class_public_instance_methods(1, args, CLASS_OF(obj)); - } - return rb_class_public_instance_methods(argc, argv, CLASS_OF(obj)); -} - -/* - * call-seq: - * obj.instance_variable_get(symbol) => obj - * - * Returns the value of the given instance variable, or nil if the - * instance variable is not set. The @ part of the - * variable name should be included for regular instance - * variables. Throws a NameError exception if the - * supplied symbol is not valid as an instance variable name. - * - * class Fred - * def initialize(p1, p2) - * @a, @b = p1, p2 - * end - * end - * fred = Fred.new('cat', 99) - * fred.instance_variable_get(:@a) #=> "cat" - * fred.instance_variable_get("@b") #=> 99 - */ - -static VALUE -rb_obj_ivar_get(obj, iv) - VALUE obj, iv; -{ - ID id = rb_to_id(iv); - - if (!rb_is_instance_id(id)) { - rb_name_error(id, "`%s' is not allowed as an instance variable name", rb_id2name(id)); - } - return rb_ivar_get(obj, id); -} - -/* - * call-seq: - * obj.instance_variable_set(symbol, obj) => obj - * - * Sets the instance variable names by symbol to - * object, thereby frustrating the efforts of the class's - * author to attempt to provide proper encapsulation. The variable - * did not have to exist prior to this call. - * - * class Fred - * def initialize(p1, p2) - * @a, @b = p1, p2 - * end - * end - * fred = Fred.new('cat', 99) - * fred.instance_variable_set(:@a, 'dog') #=> "dog" - * fred.instance_variable_set(:@c, 'cat') #=> "cat" - * fred.inspect #=> "#" - */ - -static VALUE -rb_obj_ivar_set(obj, iv, val) - VALUE obj, iv, val; -{ - ID id = rb_to_id(iv); - - if (!rb_is_instance_id(id)) { - rb_name_error(id, "`%s' is not allowed as an instance variable name", rb_id2name(id)); - } - return rb_ivar_set(obj, id, val); -} - -/* - * call-seq: - * obj.instance_variable_defined?(symbol) => true or false - * - * Returns true if the given instance variable is - * defined in obj. - * - * class Fred - * def initialize(p1, p2) - * @a, @b = p1, p2 - * end - * end - * fred = Fred.new('cat', 99) - * fred.instance_variable_defined?(:@a) #=> true - * fred.instance_variable_defined?("@b") #=> true - * fred.instance_variable_defined?("@c") #=> false - */ - -static VALUE -rb_obj_ivar_defined(obj, iv) - VALUE obj, iv; -{ - ID id = rb_to_id(iv); - - if (!rb_is_instance_id(id)) { - rb_name_error(id, "`%s' is not allowed as an instance variable name", rb_id2name(id)); - } - return rb_ivar_defined(obj, id); -} - -/* - * call-seq: - * mod.class_variable_get(symbol) => obj - * - * Returns the value of the given class variable (or throws a - * NameError exception). The @@ part of the - * variable name should be included for regular class variables - * - * class Fred - * @@foo = 99 - * end - * - * def Fred.foo - * class_variable_get(:@@foo) #=> 99 - * end - */ - -static VALUE -rb_mod_cvar_get(obj, iv) - VALUE obj, iv; -{ - ID id = rb_to_id(iv); - - if (!rb_is_class_id(id)) { - rb_name_error(id, "`%s' is not allowed as a class variable name", rb_id2name(id)); - } - return rb_cvar_get(obj, id); -} - -/* - * call-seq: - * obj.class_variable_set(symbol, obj) => obj - * - * Sets the class variable names by symbol to - * object. - * - * class Fred - * @@foo = 99 - * def foo - * @@foo - * end - * end - * - * def Fred.foo - * class_variable_set(:@@foo, 101) #=> 101 - * end - * Fred.foo - * Fred.new.foo #=> 101 - */ - -static VALUE -rb_mod_cvar_set(obj, iv, val) - VALUE obj, iv, val; -{ - ID id = rb_to_id(iv); - - if (!rb_is_class_id(id)) { - rb_name_error(id, "`%s' is not allowed as a class variable name", rb_id2name(id)); - } - rb_cvar_set(obj, id, val, Qfalse); - return val; -} - -/* - * call-seq: - * obj.class_variable_defined?(symbol) => true or false - * - * Returns true if the given class variable is defined - * in obj. - * - * class Fred - * @@foo = 99 - * end - * Fred.class_variable_defined?(:@@foo) #=> true - * Fred.class_variable_defined?(:@@bar) #=> false - */ - -static VALUE -rb_mod_cvar_defined(obj, iv) - VALUE obj, iv; -{ - ID id = rb_to_id(iv); - - if (!rb_is_class_id(id)) { - rb_name_error(id, "`%s' is not allowed as a class variable name", rb_id2name(id)); - } - return rb_cvar_defined(obj, id); -} - -static VALUE -convert_type(val, tname, method, raise) - VALUE val; - const char *tname, *method; - int raise; -{ - ID m; - - m = rb_intern(method); - if (!rb_respond_to(val, m)) { - if (raise) { - rb_raise(rb_eTypeError, "can't convert %s into %s", - NIL_P(val) ? "nil" : - val == Qtrue ? "true" : - val == Qfalse ? "false" : - rb_obj_classname(val), - tname); - } - else { - return Qnil; - } - } - return rb_funcall(val, m, 0); -} - -VALUE -rb_convert_type(val, type, tname, method) - VALUE val; - int type; - const char *tname, *method; -{ - VALUE v; - - if (TYPE(val) == type) return val; - v = convert_type(val, tname, method, Qtrue); - if (TYPE(v) != type) { - rb_raise(rb_eTypeError, "%s#%s should return %s", - rb_obj_classname(val), method, tname); - } - return v; -} - -VALUE -rb_check_convert_type(val, type, tname, method) - VALUE val; - int type; - const char *tname, *method; -{ - VALUE v; - - /* always convert T_DATA */ - if (TYPE(val) == type && type != T_DATA) return val; - v = convert_type(val, tname, method, Qfalse); - if (NIL_P(v)) return Qnil; - if (TYPE(v) != type) { - rb_raise(rb_eTypeError, "%s#%s should return %s", - rb_obj_classname(val), method, tname); - } - return v; -} - - -static VALUE -rb_to_integer(val, method) - VALUE val; - const char *method; -{ - VALUE v = convert_type(val, "Integer", method, Qtrue); - if (!rb_obj_is_kind_of(v, rb_cInteger)) { - rb_raise(rb_eTypeError, "%s#%s should return Integer", - rb_obj_classname(val), method); - } - return v; -} - -VALUE -rb_to_int(val) - VALUE val; -{ - return rb_to_integer(val, "to_int"); -} - -VALUE -rb_Integer(val) - VALUE val; -{ - VALUE tmp; - - switch (TYPE(val)) { - case T_FLOAT: - if (RFLOAT(val)->value <= (double)FIXNUM_MAX - && RFLOAT(val)->value >= (double)FIXNUM_MIN) { - break; - } - return rb_dbl2big(RFLOAT(val)->value); - - case T_FIXNUM: - case T_BIGNUM: - return val; - - case T_STRING: - return rb_str_to_inum(val, 0, Qtrue); - - default: - break; - } - tmp = convert_type(val, "Integer", "to_int", Qfalse); - if (NIL_P(tmp)) { - return rb_to_integer(val, "to_i"); - } - return tmp; -} - -/* - * call-seq: - * Integer(arg) => integer - * - * Converts arg to a Fixnum or Bignum. - * Numeric types are converted directly (with floating point numbers - * being truncated). If arg is a String, leading - * radix indicators (0, 0b, and - * 0x) are honored. Others are converted using - * to_int and to_i. This behavior is - * different from that of String#to_i. - * - * Integer(123.999) #=> 123 - * Integer("0x1a") #=> 26 - * Integer(Time.new) #=> 1049896590 - */ - -static VALUE -rb_f_integer(obj, arg) - VALUE obj, arg; -{ - return rb_Integer(arg); -} - -double -rb_cstr_to_dbl(p, badcheck) - const char *p; - int badcheck; -{ - const char *q; - char *end; - double d; - const char *ellipsis = ""; - int w; -#define OutOfRange() (((w = end - p) > 20) ? (w = 20, ellipsis = "...") : (ellipsis = "")) - - if (!p) return 0.0; - q = p; - if (badcheck) { - while (ISSPACE(*p)) p++; - } - else { - while (ISSPACE(*p) || *p == '_') p++; - } - errno = 0; - d = strtod(p, &end); - if (errno == ERANGE) { - OutOfRange(); - rb_warn("Float %.*s%s out of range", w, p, ellipsis); - errno = 0; - } - if (p == end) { - if (badcheck) { - bad: - rb_invalid_str(q, "Float()"); - } - return d; - } - if (*end) { - char *buf = ALLOCA_N(char, strlen(p)+1); - char *n = buf; - - while (p < end) *n++ = *p++; - while (*p) { - if (*p == '_') { - /* remove underscores between digits */ - if (badcheck) { - if (n == buf || !ISDIGIT(n[-1])) goto bad; - ++p; - if (!ISDIGIT(*p)) goto bad; - } - else { - while (*++p == '_'); - continue; - } - } - *n++ = *p++; - } - *n = '\0'; - p = buf; - d = strtod(p, &end); - if (errno == ERANGE) { - OutOfRange(); - rb_warn("Float %.*s%s out of range", w, p, ellipsis); - errno = 0; - } - if (badcheck) { - if (!end || p == end) goto bad; - while (*end && ISSPACE(*end)) end++; - if (*end) goto bad; - } - } - if (errno == ERANGE) { - errno = 0; - OutOfRange(); - rb_raise(rb_eArgError, "Float %.*s%s out of range", w, q, ellipsis); - } - return d; -} - -double -rb_str_to_dbl(str, badcheck) - VALUE str; - int badcheck; -{ - char *s; - long len; - - StringValue(str); - s = RSTRING(str)->ptr; - len = RSTRING(str)->len; - if (s) { - if (s[len]) { /* no sentinel somehow */ - char *p = ALLOCA_N(char, len+1); - - MEMCPY(p, s, char, len); - p[len] = '\0'; - s = p; - } - if (badcheck && len != strlen(s)) { - rb_raise(rb_eArgError, "string for Float contains null byte"); - } - } - return rb_cstr_to_dbl(s, badcheck); -} - -VALUE -rb_Float(val) - VALUE val; -{ - switch (TYPE(val)) { - case T_FIXNUM: - return rb_float_new((double)FIX2LONG(val)); - - case T_FLOAT: - return val; - - case T_BIGNUM: - return rb_float_new(rb_big2dbl(val)); - - case T_STRING: - return rb_float_new(rb_str_to_dbl(val, Qtrue)); - - case T_NIL: - rb_raise(rb_eTypeError, "can't convert nil into Float"); - break; - - default: - { - VALUE f = rb_convert_type(val, T_FLOAT, "Float", "to_f"); - if (isnan(RFLOAT(f)->value)) { - rb_raise(rb_eArgError, "invalid value for Float()"); - } - return f; - } - } -} - -/* - * call-seq: - * Float(arg) => float - * - * Returns arg converted to a float. Numeric types are converted - * directly, the rest are converted using arg.to_f. As of Ruby - * 1.8, converting nil generates a TypeError. - * - * Float(1) #=> 1.0 - * Float("123.456") #=> 123.456 - */ - -static VALUE -rb_f_float(obj, arg) - VALUE obj, arg; -{ - return rb_Float(arg); -} - -double -rb_num2dbl(val) - VALUE val; -{ - switch (TYPE(val)) { - case T_FLOAT: - return RFLOAT(val)->value; - - case T_STRING: - rb_raise(rb_eTypeError, "no implicit conversion to float from string"); - break; - - case T_NIL: - rb_raise(rb_eTypeError, "no implicit conversion to float from nil"); - break; - - default: - break; - } - - return RFLOAT(rb_Float(val))->value; -} - -char* -rb_str2cstr(str, len) - VALUE str; - long *len; -{ - StringValue(str); - if (len) *len = RSTRING(str)->len; - else if (RTEST(ruby_verbose) && RSTRING(str)->len != strlen(RSTRING(str)->ptr)) { - rb_warn("string contains \\0 character"); - } - return RSTRING(str)->ptr; -} - -VALUE -rb_String(val) - VALUE val; -{ - return rb_convert_type(val, T_STRING, "String", "to_s"); -} - - -/* - * call-seq: - * String(arg) => string - * - * Converts arg to a String by calling its - * to_s method. - * - * String(self) #=> "main" - * String(self.class #=> "Object" - * String(123456) #=> "123456" - */ - -static VALUE -rb_f_string(obj, arg) - VALUE obj, arg; -{ - return rb_String(arg); -} - -#if 0 -VALUE -rb_Array(val) - VALUE val; -{ - VALUE tmp = rb_check_array_type(val); - - if (NIL_P(tmp)) { - tmp = rb_check_convert_type(val, T_ARRAY, "Array", "to_a"); - if (NIL_P(tmp)) { - return rb_ary_new3(1, val); - } - } - return tmp; -} -#endif - -/* - * call-seq: - * Array(arg) => array - * - * Returns arg as an Array. First tries to call - * arg.to_ary, then arg.to_a. - * If both fail, creates a single element array containing arg - * (unless arg is nil). - * - * Array(1..5) #=> [1, 2, 3, 4, 5] - */ - -static VALUE -rb_f_array(obj, arg) - VALUE obj, arg; -{ - return rb_Array(arg); -} - -static VALUE -boot_defclass(name, super) - char *name; - VALUE super; -{ - extern st_table *rb_class_tbl; - VALUE obj = rb_class_boot(super); - ID id = rb_intern(name); - - rb_name_class(obj, id); - st_add_direct(rb_class_tbl, id, obj); - rb_const_set((rb_cObject ? rb_cObject : obj), id, obj); - return obj; -} - -VALUE ruby_top_self; - -/* - * Document-class: Class - * - * Classes in Ruby are first-class objects---each is an instance of - * class Class. - * - * When a new class is created (typically using class Name ... - * end), an object of type Class is created and - * assigned to a global constant (Name in this case). When - * Name.new is called to create a new object, the - * new method in Class is run by default. - * This can be demonstrated by overriding new in - * Class: - * - * class Class - * alias oldNew new - * def new(*args) - * print "Creating a new ", self.name, "\n" - * oldNew(*args) - * end - * end - * - * - * class Name - * end - * - * - * n = Name.new - * - * produces: - * - * Creating a new Name - * - * Classes, modules, and objects are interrelated. In the diagram - * that follows, the vertical arrows represent inheritance, and the - * parentheses meta-classes. All metaclasses are instances - * of the class `Class'. - * - * +------------------+ - * | | - * Object---->(Object) | - * ^ ^ ^ ^ | - * | | | | | - * | | +-----+ +---------+ | - * | | | | | - * | +-----------+ | | - * | | | | | - * +------+ | Module--->(Module) | - * | | ^ ^ | - * OtherClass-->(OtherClass) | | | - * | | | - * Class---->(Class) | - * ^ | - * | | - * +----------------+ - */ - - -/* - * Object is the parent class of all classes in Ruby. Its - * methods are therefore available to all objects unless explicitly - * overridden. - * - * Object mixes in the Kernel module, making - * the built-in kernel functions globally accessible. Although the - * instance methods of Object are defined by the - * Kernel module, we have chosen to document them here for - * clarity. - * - * In the descriptions of Object's methods, the parameter symbol refers - * to a symbol, which is either a quoted string or a - * Symbol (such as :name). - */ - -void -Init_Object() -{ - VALUE metaclass; - - rb_cObject = boot_defclass("Object", 0); - rb_cModule = boot_defclass("Module", rb_cObject); - rb_cClass = boot_defclass("Class", rb_cModule); - - metaclass = rb_make_metaclass(rb_cObject, rb_cClass); - metaclass = rb_make_metaclass(rb_cModule, metaclass); - metaclass = rb_make_metaclass(rb_cClass, metaclass); - - rb_mKernel = rb_define_module("Kernel"); - rb_include_module(rb_cObject, rb_mKernel); - rb_define_alloc_func(rb_cObject, rb_class_allocate_instance); - rb_define_private_method(rb_cObject, "initialize", rb_obj_dummy, 0); - rb_define_private_method(rb_cClass, "inherited", rb_obj_dummy, 1); - rb_define_private_method(rb_cModule, "included", rb_obj_dummy, 1); - rb_define_private_method(rb_cModule, "extended", rb_obj_dummy, 1); - rb_define_private_method(rb_cModule, "method_added", rb_obj_dummy, 1); - rb_define_private_method(rb_cModule, "method_removed", rb_obj_dummy, 1); - rb_define_private_method(rb_cModule, "method_undefined", rb_obj_dummy, 1); - - - rb_define_method(rb_mKernel, "nil?", rb_false, 0); - rb_define_method(rb_mKernel, "==", rb_obj_equal, 1); - rb_define_method(rb_mKernel, "equal?", rb_obj_equal, 1); - rb_define_method(rb_mKernel, "===", rb_equal, 1); - rb_define_method(rb_mKernel, "=~", rb_obj_pattern_match, 1); - - rb_define_method(rb_mKernel, "eql?", rb_obj_equal, 1); - - rb_define_method(rb_mKernel, "id", rb_obj_id_obsolete, 0); - rb_define_method(rb_mKernel, "type", rb_obj_type, 0); - rb_define_method(rb_mKernel, "class", rb_obj_class, 0); - - rb_define_method(rb_mKernel, "clone", rb_obj_clone, 0); - rb_define_method(rb_mKernel, "dup", rb_obj_dup, 0); - rb_define_method(rb_mKernel, "initialize_copy", rb_obj_init_copy, 1); - - rb_define_method(rb_mKernel, "taint", rb_obj_taint, 0); - rb_define_method(rb_mKernel, "tainted?", rb_obj_tainted, 0); - rb_define_method(rb_mKernel, "untaint", rb_obj_untaint, 0); - rb_define_method(rb_mKernel, "freeze", rb_obj_freeze, 0); - rb_define_method(rb_mKernel, "frozen?", rb_obj_frozen_p, 0); - - rb_define_method(rb_mKernel, "to_a", rb_any_to_a, 0); /* to be removed */ - rb_define_method(rb_mKernel, "to_s", rb_any_to_s, 0); - rb_define_method(rb_mKernel, "inspect", rb_obj_inspect, 0); - rb_define_method(rb_mKernel, "methods", rb_obj_methods, -1); - rb_define_method(rb_mKernel, "singleton_methods", - rb_obj_singleton_methods, -1); /* in class.c */ - rb_define_method(rb_mKernel, "protected_methods", - rb_obj_protected_methods, -1); - rb_define_method(rb_mKernel, "private_methods", rb_obj_private_methods, -1); - rb_define_method(rb_mKernel, "public_methods", rb_obj_public_methods, -1); - rb_define_method(rb_mKernel, "instance_variables", - rb_obj_instance_variables, 0); /* in variable.c */ - rb_define_method(rb_mKernel, "instance_variable_get", rb_obj_ivar_get, 1); - rb_define_method(rb_mKernel, "instance_variable_set", rb_obj_ivar_set, 2); - rb_define_method(rb_mKernel, "instance_variable_defined?", rb_obj_ivar_defined, 1); - rb_define_private_method(rb_mKernel, "remove_instance_variable", - rb_obj_remove_instance_variable, 1); /* in variable.c */ - - rb_define_method(rb_mKernel, "instance_of?", rb_obj_is_instance_of, 1); - rb_define_method(rb_mKernel, "kind_of?", rb_obj_is_kind_of, 1); - rb_define_method(rb_mKernel, "is_a?", rb_obj_is_kind_of, 1); - - rb_define_private_method(rb_mKernel, "singleton_method_added", rb_obj_dummy, 1); - rb_define_private_method(rb_mKernel, "singleton_method_removed", rb_obj_dummy, 1); - rb_define_private_method(rb_mKernel, "singleton_method_undefined", rb_obj_dummy, 1); - - rb_define_global_function("sprintf", rb_f_sprintf, -1); /* in sprintf.c */ - rb_define_global_function("format", rb_f_sprintf, -1); /* in sprintf.c */ - - rb_define_global_function("Integer", rb_f_integer, 1); - rb_define_global_function("Float", rb_f_float, 1); - - rb_define_global_function("String", rb_f_string, 1); - rb_define_global_function("Array", rb_f_array, 1); - - rb_cNilClass = rb_define_class("NilClass", rb_cObject); - rb_define_method(rb_cNilClass, "to_i", nil_to_i, 0); - rb_define_method(rb_cNilClass, "to_f", nil_to_f, 0); - rb_define_method(rb_cNilClass, "to_s", nil_to_s, 0); - rb_define_method(rb_cNilClass, "to_a", nil_to_a, 0); - rb_define_method(rb_cNilClass, "inspect", nil_inspect, 0); - rb_define_method(rb_cNilClass, "&", false_and, 1); - rb_define_method(rb_cNilClass, "|", false_or, 1); - rb_define_method(rb_cNilClass, "^", false_xor, 1); - - rb_define_method(rb_cNilClass, "nil?", rb_true, 0); - rb_undef_alloc_func(rb_cNilClass); - rb_undef_method(CLASS_OF(rb_cNilClass), "new"); - rb_define_global_const("NIL", Qnil); - - rb_cSymbol = rb_define_class("Symbol", rb_cObject); - rb_define_singleton_method(rb_cSymbol, "all_symbols", - rb_sym_all_symbols, 0); /* in parse.y */ - rb_undef_alloc_func(rb_cSymbol); - rb_undef_method(CLASS_OF(rb_cSymbol), "new"); - - rb_define_method(rb_cSymbol, "to_i", sym_to_i, 0); - rb_define_method(rb_cSymbol, "to_int", sym_to_int, 0); - rb_define_method(rb_cSymbol, "inspect", sym_inspect, 0); - rb_define_method(rb_cSymbol, "to_s", sym_to_s, 0); - rb_define_method(rb_cSymbol, "id2name", sym_to_s, 0); - rb_define_method(rb_cSymbol, "to_sym", sym_to_sym, 0); - rb_define_method(rb_cSymbol, "===", rb_obj_equal, 1); - - rb_define_method(rb_cModule, "freeze", rb_mod_freeze, 0); - rb_define_method(rb_cModule, "===", rb_mod_eqq, 1); - rb_define_method(rb_cModule, "==", rb_obj_equal, 1); - rb_define_method(rb_cModule, "<=>", rb_mod_cmp, 1); - rb_define_method(rb_cModule, "<", rb_mod_lt, 1); - rb_define_method(rb_cModule, "<=", rb_class_inherited_p, 1); - rb_define_method(rb_cModule, ">", rb_mod_gt, 1); - rb_define_method(rb_cModule, ">=", rb_mod_ge, 1); - rb_define_method(rb_cModule, "initialize_copy", rb_mod_init_copy, 1); /* in class.c */ - rb_define_method(rb_cModule, "to_s", rb_mod_to_s, 0); - rb_define_method(rb_cModule, "included_modules", - rb_mod_included_modules, 0); /* in class.c */ - rb_define_method(rb_cModule, "include?", rb_mod_include_p, 1); /* in class.c */ - rb_define_method(rb_cModule, "name", rb_mod_name, 0); /* in variable.c */ - rb_define_method(rb_cModule, "ancestors", rb_mod_ancestors, 0); /* in class.c */ - - rb_define_private_method(rb_cModule, "attr", rb_mod_attr, -1); - rb_define_private_method(rb_cModule, "attr_reader", rb_mod_attr_reader, -1); - rb_define_private_method(rb_cModule, "attr_writer", rb_mod_attr_writer, -1); - rb_define_private_method(rb_cModule, "attr_accessor", rb_mod_attr_accessor, -1); - - rb_define_alloc_func(rb_cModule, rb_module_s_alloc); - rb_define_method(rb_cModule, "initialize", rb_mod_initialize, 0); - rb_define_method(rb_cModule, "instance_methods", - rb_class_instance_methods, -1); /* in class.c */ - rb_define_method(rb_cModule, "public_instance_methods", - rb_class_public_instance_methods, -1); /* in class.c */ - rb_define_method(rb_cModule, "protected_instance_methods", - rb_class_protected_instance_methods, -1); /* in class.c */ - rb_define_method(rb_cModule, "private_instance_methods", - rb_class_private_instance_methods, -1); /* in class.c */ - - rb_define_method(rb_cModule, "class_variable_defined?", rb_mod_cvar_defined, 1); - rb_define_method(rb_cModule, "constants", rb_mod_constants, 0); /* in variable.c */ - rb_define_method(rb_cModule, "const_get", rb_mod_const_get, 1); - rb_define_method(rb_cModule, "const_set", rb_mod_const_set, 2); - rb_define_method(rb_cModule, "const_defined?", rb_mod_const_defined, 1); - rb_define_private_method(rb_cModule, "remove_const", - rb_mod_remove_const, 1); /* in variable.c */ - rb_define_method(rb_cModule, "const_missing", - rb_mod_const_missing, 1); /* in variable.c */ - rb_define_method(rb_cModule, "class_variables", - rb_mod_class_variables, 0); /* in variable.c */ - rb_define_private_method(rb_cModule, "remove_class_variable", - rb_mod_remove_cvar, 1); /* in variable.c */ - rb_define_private_method(rb_cModule, "class_variable_get", rb_mod_cvar_get, 1); - rb_define_private_method(rb_cModule, "class_variable_set", rb_mod_cvar_set, 2); - - rb_define_method(rb_cClass, "allocate", rb_obj_alloc, 0); - rb_define_method(rb_cClass, "new", rb_class_new_instance, -1); - rb_define_method(rb_cClass, "initialize", rb_class_initialize, -1); - rb_define_method(rb_cClass, "initialize_copy", rb_class_init_copy, 1); /* in class.c */ - rb_define_method(rb_cClass, "superclass", rb_class_superclass, 0); - rb_define_alloc_func(rb_cClass, rb_class_s_alloc); - rb_undef_method(rb_cClass, "extend_object"); - rb_undef_method(rb_cClass, "append_features"); - - rb_cData = rb_define_class("Data", rb_cObject); - rb_undef_alloc_func(rb_cData); - - rb_global_variable(&ruby_top_self); - ruby_top_self = rb_obj_alloc(rb_cObject); - rb_define_singleton_method(ruby_top_self, "to_s", main_to_s, 0); - - rb_cTrueClass = rb_define_class("TrueClass", rb_cObject); - rb_define_method(rb_cTrueClass, "to_s", true_to_s, 0); - rb_define_method(rb_cTrueClass, "&", true_and, 1); - rb_define_method(rb_cTrueClass, "|", true_or, 1); - rb_define_method(rb_cTrueClass, "^", true_xor, 1); - rb_undef_alloc_func(rb_cTrueClass); - rb_undef_method(CLASS_OF(rb_cTrueClass), "new"); - rb_define_global_const("TRUE", Qtrue); - - rb_cFalseClass = rb_define_class("FalseClass", rb_cObject); - rb_define_method(rb_cFalseClass, "to_s", false_to_s, 0); - rb_define_method(rb_cFalseClass, "&", false_and, 1); - rb_define_method(rb_cFalseClass, "|", false_or, 1); - rb_define_method(rb_cFalseClass, "^", false_xor, 1); - rb_undef_alloc_func(rb_cFalseClass); - rb_undef_method(CLASS_OF(rb_cFalseClass), "new"); - rb_define_global_const("FALSE", Qfalse); - - id_eq = rb_intern("=="); - id_eql = rb_intern("eql?"); - id_inspect = rb_intern("inspect"); - id_init_copy = rb_intern("initialize_copy"); -} -- cgit v1.2.3