diff --git a/bignum.c b/bignum.c index 7c3e029d57..9fe9a33fa5 100644 --- a/bignum.c +++ b/bignum.c @@ -688,6 +688,20 @@ rb_big2str(x, base) return ss; } +/* + * call-seq: + * big.to_s(base=10) => string + * + * Returns a string containing the representation of big radix + * base (2 through 36). + * + * 12345654321.to_s #=> "12345654321" + * 12345654321.to_s(2) #=> "1011011111110110111011110000110001" + * 12345654321.to_s(8) #=> "133766736061" + * 12345654321.to_s(16) #=> "2dfdbbc31" + * 78546939656932.to_s(36) #=> "rubyrules" + */ + static VALUE rb_big_to_s(argc, argv, x) int argc; @@ -935,6 +949,13 @@ rb_big_eql(x, y) return Qtrue; } +/* + * call-seq: + * -big => other_big + * + * Unary minus (returns a new Bignum whose value is 0-big) + */ + static VALUE rb_big_uminus(x) VALUE x; @@ -1054,6 +1075,13 @@ bigadd(x, y, sign) return z; } +/* + * call-seq: + * big + other => Numeric + * + * Adds big and other, returning the result. + */ + VALUE rb_big_plus(x, y) VALUE x, y; @@ -1073,6 +1101,13 @@ rb_big_plus(x, y) } } +/* + * call-seq: + * big - other => Numeric + * + * Subtracts other from big, returning the result. + */ + VALUE rb_big_minus(x, y) VALUE x, y; @@ -1092,6 +1127,13 @@ rb_big_minus(x, y) } } +/* + * call-seq: + * big * other => Numeric + * + * Multiplies big and other, returning the result. + */ + VALUE rb_big_mul(x, y) VALUE x, y; @@ -1287,6 +1329,14 @@ bigdivmod(x, y, divp, modp) } } +/* + * call-seq: + * big / other => Numeric + * big.div(other) => Numeric + * + * Divides big by other, returning the result. + */ + static VALUE rb_big_div(x, y) VALUE x, y; @@ -1312,6 +1362,15 @@ rb_big_div(x, y) return bignorm(z); } +/* + * call-seq: + * big % other => Numeric + * big.modulo(other) => Numeric + * + * Returns big modulo other. See Numeric.divmod for more + * information. + */ + static VALUE rb_big_modulo(x, y) VALUE x, y; @@ -1334,6 +1393,15 @@ rb_big_modulo(x, y) return bignorm(z); } +/* + * call-seq: + * big.remainder(numeric) => number + * + * Returns the remainder after dividing big by numeric. + * + * -1234567890987654321.remainder(13731) #=> -6966 + * -1234567890987654321.remainder(13731.24) #=> -9906.22531493148 + */ static VALUE rb_big_remainder(x, y) VALUE x, y; @@ -1356,6 +1424,13 @@ rb_big_remainder(x, y) return bignorm(z); } +/* + * call-seq: + * big.divmod(numeric) => array + * + * See Numeric#divmod. + * + */ VALUE rb_big_divmod(x, y) VALUE x, y; @@ -1378,6 +1453,18 @@ rb_big_divmod(x, y) return rb_assoc_new(bignorm(div), bignorm(mod)); } +/* + * call-seq: + * big.quo(numeric) -> float + * + * Returns the floating point result of dividing big by + * numeric. + * + * -1234567890987654321.quo(13731) #=> -89910996357705.5 + * -1234567890987654321.quo(13731.24) #=> -89909424858035.7 + * + */ + static VALUE rb_big_quo(x, y) VALUE x, y; @@ -1404,6 +1491,19 @@ rb_big_quo(x, y) return rb_float_new(dx / dy); } +/* + * call-seq: + * big ** exponent #=> numeric + * + * Raises _big_ to the _exponent_ power (which may be an integer, float, + * or anything that will coerce to a number). The result may be + * a Fixnum, Bignum, or Float + * + * 123456789 ** 2 #=> 15241578750190521 + * 123456789 ** 1.2 #=> 5126464716.09932 + * 123456789 ** -2 #=> 6.5610001194102e-17 + */ + VALUE rb_big_pow(x, y) VALUE x, y; @@ -1447,6 +1547,13 @@ rb_big_pow(x, y) return rb_float_new(pow(rb_big2dbl(x), d)); } +/* + * call-seq: + * big & numeric => integer + * + * Performs bitwise +and+ between _big_ and _numeric_. + */ + VALUE rb_big_and(x, y) VALUE x, y; @@ -1716,6 +1823,10 @@ rb_big_hash(x) return LONG2FIX(key); } +/* + * MISSING: documentation + */ + static VALUE rb_big_coerce(x, y) VALUE x, y; @@ -1768,6 +1879,24 @@ rb_big_size(big) return LONG2FIX(RBIGNUM(big)->len*SIZEOF_BDIGITS); } +/* + * Bignum objects hold integers outside the range of + * Fixnum. Bignum objects are created + * automatically when integer calculations would otherwise overflow a + * Fixnum. When a calculation involving + * Bignum objects returns a result that will fit in a + * Fixnum, the result is automatically converted. + * + * For the purposes of the bitwise operations and [], a + * Bignum is treated as if it were an infinite-length + * bitstring with 2's complement representation. + * + * While Fixnum values are immediate, Bignum + * objects are not---assignment and parameter passing work with + * references to objects, not the objects themselves. + * + */ + void Init_Bignum() { diff --git a/compar.c b/compar.c index 5376ce4452..1488b2c65d 100644 --- a/compar.c +++ b/compar.c @@ -69,6 +69,15 @@ cmp_failed() return Qnil; } +/* + * call-seq: + * obj == other => true or false + * + * Compares two objects based on the receiver's <=> + * method, returning true if it returns 0. Also returns true if + * _obj_ and _other_ are the same object. + */ + static VALUE cmp_equal(x, y) VALUE x, y; @@ -81,6 +90,14 @@ cmp_equal(x, y) return rb_rescue(cmp_eq, (VALUE)a, cmp_failed, 0); } +/* + * call-seq: + * obj > other => true or false + * + * Compares two objects based on the receiver's <=> + * method, returning true if it returns 1. + */ + static VALUE cmp_gt(x, y) VALUE x, y; @@ -92,6 +109,14 @@ cmp_gt(x, y) return Qfalse; } +/* + * call-seq: + * obj >= other => true or false + * + * Compares two objects based on the receiver's <=> + * method, returning true if it returns 0 or 1. + */ + static VALUE cmp_ge(x, y) VALUE x, y; @@ -103,6 +128,14 @@ cmp_ge(x, y) return Qfalse; } +/* + * call-seq: + * obj < other => true or false + * + * Compares two objects based on the receiver's <=> + * method, returning true if it returns -1. + */ + static VALUE cmp_lt(x, y) VALUE x, y; @@ -114,6 +147,15 @@ cmp_lt(x, y) return Qfalse; } + +/* + * call-seq: + * obj <= other => true or false + * + * Compares two objects based on the receiver's <=> + * method, returning true if it returns -1 or 0. + */ + static VALUE cmp_le(x, y) VALUE x, y; @@ -125,6 +167,21 @@ cmp_le(x, y) return Qfalse; } +/* + * call-seq: + * obj.between?(min, max) => true or false + * + * Returns false if obj <=> + * min is less than zero or if anObject <=> + * max is greater than zero, true otherwise. + * + * 3.between?(1, 5) #=> true + * 6.between?(1, 5) #=> false + * 'cat'.between?('ant', 'dog') #=> true + * 'gnu'.between?('ant', 'dog') #=> false + * + */ + static VALUE cmp_between(x, min, max) VALUE x, min, max; @@ -134,6 +191,43 @@ cmp_between(x, min, max) return Qtrue; } +/* + * The Comparable mixin is used by classes whose objects + * may be ordered. The class must define the <=> operator, + * which compares the receiver against another object, returning -1, 0, + * or +1 depending on whether the receiver is less than, equal to, or + * greater than the other object. Comparable uses + * <=> to implement the conventional comparison operators + * (<, <=, ==, >=, + * and >) and the method between?. + * + * class SizeMatters + * include Comparable + * attr :str + * def <=>(anOther) + * str.size <=> anOther.str.size + * end + * def initialize(str) + * @str = str + * end + * def inspect + * @str + * end + * end + * + * s1 = SizeMatters.new("Z") + * s2 = SizeMatters.new("YY") + * s3 = SizeMatters.new("XXX") + * s4 = SizeMatters.new("WWWW") + * s5 = SizeMatters.new("VVVVV") + * + * s1 < s2 #=> true + * s4.between?(s1, s3) #=> false + * s4.between?(s3, s5) #=> true + * [ s3, s2, s5, s4, s1 ].sort #=> [Z, YY, XXX, WWWW, VVVVV] + * + */ + void Init_Comparable() { diff --git a/lib/rdoc/generators/ri_generator.rb b/lib/rdoc/generators/ri_generator.rb index c2b5269c3c..4e842d09e9 100644 --- a/lib/rdoc/generators/ri_generator.rb +++ b/lib/rdoc/generators/ri_generator.rb @@ -236,7 +236,13 @@ module Generators namespace = rdr.top_level_namespace namespace = rdr.lookup_namespace_in(cls_desc.name, namespace) if namespace.empty? - raise RiError.new("Nothing known about #{arg}") + $stderr.puts "You asked me to merge this source into existing " + $stderr.puts "documentation. This file references a class or " + $stderr.puts "module called #{cls_desc.name} which I don't" + $stderr.puts "have existing documentation for." + $stderr.puts + $stderr.puts "Perhaps you need to generate its documentation first" + exit 1 else old_cls = namespace[0] end diff --git a/lib/rdoc/ri/ri_descriptions.rb b/lib/rdoc/ri/ri_descriptions.rb index 47984cf41d..9e280abf94 100644 --- a/lib/rdoc/ri/ri_descriptions.rb +++ b/lib/rdoc/ri/ri_descriptions.rb @@ -5,29 +5,64 @@ require 'yaml' # tree. ri then reads these to generate the documentation module RI - Alias = Struct.new(:old_name, :new_name) - AliasName = Struct.new(:name) - Attribute = Struct.new(:name, :rw, :comment) - Constant = Struct.new(:name, :value, :comment) - IncludedModule = Struct.new(:name) - - class MethodSummary - attr_accessor :name - def initialize(name="") + class NamedThing + attr_reader :name + def initialize(name) @name = name end - def <=>(other) - self.name <=> other.name + @name <=> other.name + end + + def hash + @name.hash + end + + def eql?(other) + @name.eql?(other) end end +# Alias = Struct.new(:old_name, :new_name) + + class AliasName < NamedThing + end + + class Attribute < NamedThing + attr_reader :rw, :comment + def initialize(name, rw, comment) + super(name) + @rw = rw + @comment = comment + end + end + + class Constant < NamedThing + attr_reader :value, :comment + def initialize(name, value, comment) + super(name) + @value = value + @comment = comment + end + end + + class IncludedModule < NamedThing + end + + + class MethodSummary < NamedThing + def initialize(name="") + super + end + end + + class Description attr_accessor :name attr_accessor :full_name attr_accessor :comment - + def serialize self.to_yaml end @@ -35,6 +70,10 @@ module RI def Description.deserialize(from) YAML.load(from) end + + def <=>(other) + @name <=> other.name + end end class ClassDescription < Description @@ -48,11 +87,20 @@ module RI # merge in another class desscription into this one def merge_in(old) - @class_methods.concat(old.class_methods).sort! - @instance_methods.concat(old.instance_methods).sort! - @attributes.concat(old.attributes).sort! - @constants.concat(old.constants).sort! - @includes.concat(old.includes).sort! + merge(@class_methods, old.class_methods) + merge(@instance_methods, old.instance_methods) + merge(@attributes, old.attributes) + merge(@constants, old.constants) + merge(@includes, old.includes) + end + + private + + def merge(into, from) + names = {} + into.each {|i| names[i.name] = i } + from.each {|i| names[i.name] = i } + into.replace(names.keys.sort.map {|n| names[n]}) end end