diff options
author | dave <dave@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2003-12-16 20:28:44 +0000 |
---|---|---|
committer | dave <dave@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2003-12-16 20:28:44 +0000 |
commit | bc8c73c42a552fcc1d414c3475c64099f5a246d6 (patch) | |
tree | ebee43a2f527178f880b89405e30d630158975b7 | |
parent | 6ef31af2d178fb4916150d317ceafe156fccdf65 (diff) |
Put RDoc comments into array.c, and refine rdoc/ri to deal with stuff that arose
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@5202 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | array.c | 888 | ||||
-rwxr-xr-x | bin/ri | 16 | ||||
-rw-r--r-- | lib/rdoc/generators/ri_generator.rb | 57 | ||||
-rw-r--r-- | lib/rdoc/parsers/parse_c.rb | 35 | ||||
-rw-r--r-- | lib/rdoc/ri/ri_cache.rb | 31 | ||||
-rw-r--r-- | lib/rdoc/ri/ri_descriptions.rb | 7 | ||||
-rw-r--r-- | lib/rdoc/ri/ri_formatter.rb | 2 | ||||
-rw-r--r-- | lib/rdoc/ri/ri_reader.rb | 2 | ||||
-rw-r--r-- | lib/rdoc/ri/ri_util.rb | 10 | ||||
-rw-r--r-- | lib/rdoc/ri/ri_writer.rb | 2 |
10 files changed, 1005 insertions, 45 deletions
@@ -214,6 +214,44 @@ rb_check_array_type(ary) static VALUE rb_ary_replace _((VALUE, VALUE)); +/* + * call-seq: + * Array.new(size=0, obj=nil) + * Array.new(array) + * Array.new(size) {|i| ...} + + * Returns a new array. In the first form, the new array is + * empty. In the second it is created with _size_ copies of _obj_ + * (that is, _size_ references to the same + * _obj_). The third form creates a copy of the array + * passed as a parameter (the array is generated by calling + * to_ary on the parameter). In the last form, an array + * of the given size is created. Each element in this array is + * calculated by passing the element's index to the given block and + * storing the return value. + * + * Array.new + * Array.new(2) + * Array.new(5, "A") + * + * # only one copy of the object is created + * a = Array.new(2, Hash.new) + * a[0]['cat'] = 'feline' + * a + * a[1]['cat'] = 'Felix' + * a + * + * # here multiple copies are created + * a = Array.new(2) { Hash.new } + * a[0]['cat'] = 'feline' + * a + * + * squares = Array.new(5) {|i| i*i} + * squares + * + * copy = Array.new(squares) + */ + static VALUE rb_ary_initialize(argc, argv, ary) int argc; @@ -270,6 +308,15 @@ rb_ary_initialize(argc, argv, ary) return ary; } + +/* +* Returns a new array populated with the given objects. +* +* Array.[]( 1, 'a', /^A/ ) +* Array[ 1, 'a', /^A/ ] +* [ 1, 'a', /^A/ ] +*/ + static VALUE rb_ary_s_create(argc, argv, klass) int argc; @@ -329,6 +376,19 @@ rb_ary_store(ary, idx, val) RARRAY(ary)->ptr[idx] = val; } +/* + * call-seq: + * array << obj => array + * + * Append---Pushes the given object on to the end of this array. This + * expression returns the array itself, so several appends + * may be chained together. + * + * [ 1, 2 ] << "c" << "d" << [ 3, 4 ] + * #=> [ 1, 2, "c", "d", [ 3, 4 ] ] + * + */ + VALUE rb_ary_push(ary, item) VALUE ary; @@ -338,6 +398,19 @@ rb_ary_push(ary, item) return ary; } +/* + * call-seq: + * array.push(obj, ... ) => array + * + * Append---Pushes the given object(s) on to the end of this array. This + * expression returns the array itself, so several appends + * may be chained together. + * + * a = [ "a", "b", "c" ] + * a.push("d", "e", "f") + * #=> ["a", "b", "c", "d", "e", "f"] + */ + static VALUE rb_ary_push_m(argc, argv, ary) int argc; @@ -350,6 +423,18 @@ rb_ary_push_m(argc, argv, ary) return ary; } +/* + * call-seq: + * array.pop => obj or nil + * + * Removes the last element from <i>self</i> and returns it, or + * <code>nil</code> if the array is empty. + * + * a = [ "a", "m", "z" ] + * a.pop #=> "z" + * a #=> ["a", "m"] + */ + VALUE rb_ary_pop(ary) VALUE ary; @@ -381,6 +466,19 @@ ary_make_shared(ary) } } +/* + * call-seq: + * array.shift => obj or nil + * + * Returns the first element of <i>self</i> and removes it (shifting all + * other elements down by one). Returns <code>nil</code> if the array + * is empty. + * + * args = [ "-m", "-q", "filename" ] + * args.shift #=> "-m" + * args #=> ["-q", "filename"] + */ + VALUE rb_ary_shift(ary) VALUE ary; @@ -420,6 +518,18 @@ rb_ary_unshift(ary, item) return ary; } +/* + * call-seq: + * array.unshift(obj, ...) => array + * + * Prepends objects to the front of <i>array</i>. + * other elements up one. + * + * a = [ "b", "c", "d" ] + * a.unshift("a") #=> ["a", "b", "c", "d"] + * a.unshift(1, 2) #=> [ 1, 2, "a", "b", "c", "d"] + */ + static VALUE rb_ary_unshift_m(argc, argv, ary) int argc; @@ -488,6 +598,40 @@ rb_ary_subseq(ary, beg, len) return ary2; } +/* + * call-seq: + * array[int] => obj or nil + * array[start, length] => an_array or nil + * array[range] => an_array or nil + * array.slice(int) => obj or nil + * array.slice(start, length) => an_array or nil + * array.slice(range) => an_array or nil + * + * Element Reference---Returns the element at index _int_, + * or returns a subarray starting at index _start_ and + * continuing for _length_ elements, or returns a subarray + * specified by _range_. + * Negative indices count backward from the end of the + * array (-1 is the last element). Returns nil if any indices + * are out of range unless the index equals the array size and a + * _length_ or _range_ parameter is given, in which case an + * empty array is returned. + * + * a = [ "a", "b", "c", "d", "e" ] + * a[2] + a[0] + a[1] #=> "cab" + * a[6] #=> nil + * a[1, 2] #=> [ "b", "c" ] + * a[1..3] #=> [ "b", "c", "d" ] + * a[4..7] #=> [ "e" ] + * a[6..10] #=> nil + * a[-3, 3] #=> [ "c", "d", "e" ] + * # special cases + * a[5] #=> nil + * a[5, 1] #=> [] + * a[5..10] #=> [] + * + */ + VALUE rb_ary_aref(argc, argv, ary) int argc; @@ -531,6 +675,21 @@ rb_ary_aref(argc, argv, ary) return rb_ary_entry(ary, NUM2LONG(arg)); } +/* + * call-seq: + * array.at(int) #=> obj or nil + * + * Returns the element at index int. A + * negative index counts from the end of _self_. Returns +nil+ + * if the index is out of range. See also Array.[]. + * (Array.at is slightly faster than Array.[], as it + * does not accept ranges and so on.) + * + * a = [ "a", "b", "c", "d", "e" ] + * a.at(0) #=> "a" + * a.at(-1) #=> "e" + */ + static VALUE rb_ary_at(ary, pos) VALUE ary, pos; @@ -538,6 +697,17 @@ rb_ary_at(ary, pos) return rb_ary_entry(ary, NUM2LONG(pos)); } +/* + * call-seq: + * array.first => obj or nil + * + * Returns the first element of the array. If the array is empty, + * returns <code>nil</code>. + * + * a = [ "q", "r", "s", "t" ] + * a.first #=> "q" + */ + static VALUE rb_ary_first(argc, argv, ary) int argc; @@ -563,6 +733,17 @@ rb_ary_first(argc, argv, ary) } } +/* + * call-seq: + * array.last => obj or nil + * array.last(n) => an_array + * + * Returns the last element(s) of <i>self</i>. If the array is empty, + * the first form returns <code>nil</code>. + * + * [ "w", "x", "y", "z" ].last #=> "z" + */ + static VALUE rb_ary_last(argc, argv, ary) int argc; @@ -588,6 +769,26 @@ rb_ary_last(argc, argv, ary) } } +/* + * call-seq: + * array.fetch(index) => obj + * array.fetch(index, default ) => obj + * array.fetch(index) {|i| block } => obj + * + * Tries to return the element at position <i>index</i>. If the index + * lies outside the array, the first form throws an + * <code>IndexError</code> exception, the second form returns + * <i>default</i>, and the third form returns the value of invoking + * the block, passing in the index. Negative values of <i>idex</i> + * count from the end of the array. + * + * a = [ 11, 22, 33, 44 ] + * a.fetch(1) #=> 22 + * a.fetch(-1) #=> 44 + * a.fetch(4, 'cat') #=> "cat" + * a.fetch(4) { |i| i*i } #=> 16 + */ + static VALUE rb_ary_fetch(argc, argv, ary) int argc; @@ -618,6 +819,19 @@ rb_ary_fetch(argc, argv, ary) return RARRAY(ary)->ptr[idx]; } +/* + * call-seq: + * array.index(obj) => int or nil + * + * Returns the index of the first object in <i>self</i> such that is + * <code>==</code> to <i>obj</i>. Returns <code>nil</code> if + * no match is found. + * + * a = [ "a", "b", "c" ] + * a.index("b") #=> 1 + * a.index("z") #=> nil + */ + static VALUE rb_ary_index(ary, val) VALUE ary; @@ -632,6 +846,19 @@ rb_ary_index(ary, val) return Qnil; } +/* + * call-seq: + * array.rindex(obj) => int or nil + * + * Returns the index of the last object in <i>arr</i> + * <code>==</code> to <i>obj</i>. Returns <code>nil</code> if + * no match is found. + * + * a = [ "a", "b", "b", "b", "c" ] + * a.rindex("b") #=> 3 + * a.rindex("z") #=> nil + */ + static VALUE rb_ary_rindex(ary, val) VALUE ary; @@ -646,6 +873,14 @@ rb_ary_rindex(ary, val) return Qnil; } +/* + * call-seq: + * array.indexes( i1, i2, ... iN ) => an_array + * array.indices( i1, i2, ... iN ) => an_array + * + * Deprecated; use <code>Array#select</code>. + */ + static VALUE rb_ary_indexes(argc, argv, ary) int argc; @@ -742,6 +977,34 @@ rb_ary_update(ary, beg, len, rpl) } } +/* + * call-seq: + * array[int] = obj => obj + * array[start, length] = an_array => an_array + * array[range] = an_array => an_array + * + * Element Assignment---Sets the element at index _int_, + * or replaces a subarray starting at index _start_ and + * continuing for _length_ elements, or replaces a subarray + * specified by _range_. If _int_ is greater than + * the current capacity of the array, the array grows + * automatically. A negative _int_ will count backward + * from the end of the array. Inserts elements if _length_ is + * zero. If _an_array is +nil+, deletes elements from _self_. + * An +IndexError+ is raised if a + * negative index points past the beginning of the array. See also + * Array.push, and Array.unshift. + * + * a = Array.new + * a[4] = "4"; + * a[0, 3] = [ 'a', 'b', 'c' ] + * a[1..2] = [ 1, 2 ]; + * a[0, 2] = "?"; + * a[0..2] = "A"; + * a[-1] = "Z"; + * a[1..-1] = nil; + */ + static VALUE rb_ary_aset(argc, argv, ary) int argc; @@ -782,6 +1045,18 @@ fixnum: return argv[1]; } +/* + * call-seq: + * array.insert(index, obj...) => array + * + * Inserts the given values before the element with the given index + * (which may be negative). + * + * a = %w{ a b c d } + * a.insert(2, 99) #=> ["a", "b", 99, "c", "d"] + * a.insert(-2, 1, 2, 3) #=> ["a", "b", 99, "c", 1, 2, 3, "d"] + */ + static VALUE rb_ary_insert(argc, argv, ary) int argc; @@ -806,6 +1081,21 @@ rb_ary_insert(argc, argv, ary) return ary; } +/* + * call-seq: + * array.each {|item| block } => array + * + * Calls <i>block</i> once for each element in <i>self</i>, passing that + * element as a parameter. + * + * a = [ "a", "b", "c" ] + * a.each {|x| print x, " -- " } + * + * produces: + * + * a -- b -- c -- + */ + VALUE rb_ary_each(ary) VALUE ary; @@ -818,6 +1108,21 @@ rb_ary_each(ary) return ary; } +/* + * call-seq: + * array.each_index {|index| block } => array + * + * Same as <code>Array#each</code>, but passes the index of the element + * instead of the element itself. + * + * a = [ "a", "b", "c" ] + * a.each_index {|x| print x, " -- " } + * + * produces: + * + * 0 -- 1 -- 2 -- + */ + static VALUE rb_ary_each_index(ary) VALUE ary; @@ -830,6 +1135,21 @@ rb_ary_each_index(ary) return ary; } +/* + * call-seq: + * array.reverse_each {|item| block } + * + * Same as <code>Array#each</code>, but traverses <i>self</i> in reverse + * order. + * + * a = [ "a", "b", "c" ] + * a.reverse_each {|x| print x, " " } + * + * produces: + * + * c b a + */ + static VALUE rb_ary_reverse_each(ary) VALUE ary; @@ -845,6 +1165,15 @@ rb_ary_reverse_each(ary) return ary; } +/* + * call-seq: + * array.length -> int + * + * Returns the number of elements in <i>self</i>. May be zero. + * + * [ 1, 2, 3, 4, 5 ].length #=> 5 + */ + static VALUE rb_ary_length(ary) VALUE ary; @@ -852,6 +1181,15 @@ rb_ary_length(ary) return LONG2NUM(RARRAY(ary)->len); } +/* + * call-seq: + * array.empty? => true or false + * + * Returns <code>true</code> if <i>self</i> array contains no elements. + * + * [].empty? #=> true + */ + static VALUE rb_ary_empty_p(ary) VALUE ary; @@ -933,6 +1271,17 @@ rb_ary_join(ary, sep) return result; } +/* + * call-seq: + * array.join(sep=$,) => str + * + * Returns a string created by converting each element of the array to + * a string, separated by <i>sep</i>. + * + * [ "a", "b", "c" ].join #=> "abc" + * [ "a", "b", "c" ].join("-") #=> "a-b-c" + */ + static VALUE rb_ary_join_m(argc, argv, ary) int argc; @@ -947,6 +1296,16 @@ rb_ary_join_m(argc, argv, ary) return rb_ary_join(ary, sep); } +/* + * call-seq: + * array.to_s -> string + * + * Returns _self_<code>.join</code>. + * + * [ "a", "e", "i", "o" ].to_s #=> "aeio" + * + */ + VALUE rb_ary_to_s(ary) VALUE ary; @@ -1067,6 +1426,14 @@ rb_ary_inspect(ary) return rb_protect_inspect(inspect_ary, ary, 0); } +/* + * call-seq: + * array.to_a -> array + * + * Returns _self_. If called on a subclass of Array, converts + * the receiver to an Array object. + */ + static VALUE rb_ary_to_a(ary) VALUE ary; @@ -1079,6 +1446,13 @@ rb_ary_to_a(ary) return ary; } +/* + * call-seq: + * array.to_ary -> array + * + * Returns _self_. + */ + static VALUE rb_ary_to_ary_m(ary) VALUE ary; @@ -1107,6 +1481,17 @@ rb_ary_reverse(ary) return ary; } +/* + * call-seq: + * array.reverse! => array + * + * Reverses _self_ in place. + * + * a = [ "a", "b", "c" ] + * a.reverse! #=> ["c", "b", "a"] + * a #=> ["c", "b", "a"] + */ + static VALUE rb_ary_reverse_bang(ary) VALUE ary; @@ -1114,6 +1499,16 @@ rb_ary_reverse_bang(ary) return rb_ary_reverse(ary); } +/* + * call-seq: + * array.reverse -> an_array + * + * Returns a new array containing <i>self</i>'s elements in reverse order. + * + * [ "a", "b", "c" ].reverse #=> ["c", "b", "a"] + * [ 1 ].reverse #=> [1] + */ + static VALUE rb_ary_reverse_m(ary) VALUE ary; @@ -1167,6 +1562,22 @@ sort_unlock(ary) } VALUE +/* + * call-seq: + * array.sort! => array + * array.sort! {| a,b | block } => array + * + * Sorts _self_. Comparisons for + * the sort will be done using the <code><=></code> operator or using + * an optional code block. The block implements a comparison between + * <i>a</i> and <i>b</i>, returning -1, 0, or +1. See also + * <code>Enumerable#sort_by</code>. + * + * a = [ "d", "a", "e", "c", "b" ] + * a.sort #=> ["a", "b", "c", "d", "e"] + * a.sort {|x,y| y <=> x } #=> ["e", "d", "c", "b", "a"] + */ + rb_ary_sort_bang(ary) VALUE ary; { @@ -1178,6 +1589,22 @@ rb_ary_sort_bang(ary) return ary; } +/* + * call-seq: + * array.sort => an_array + * array.sort {| a,b | block } => an_array + * + * Returns a new array created by sorting <i>self</i>. Comparisons for + * the sort will be done using the <code><=></code> operator or using + * an optional code block. The block implements a comparison between + * <i>a</i> and <i>b</i>, returning -1, 0, or +1. See also + * <code>Enumerable#sort_by</code>. + * + * a = [ "d", "a", "e", "c", "b" ] + * a.sort #=> ["a", "b", "c", "d", "e"] + * a.sort {|x,y| y <=> x } #=> ["e", "d", "c", "b", "a"] + */ + VALUE rb_ary_sort(ary) VALUE ary; @@ -1187,6 +1614,20 @@ rb_ary_sort(ary) return ary; } +/* + * call-seq: + * array.collect {|obj| block } -> an_array + * array.map {|obj| block } -> an_array + * + * Invokes <i>block</i> once for each element of <i>self</i>. Creates a + * new array containing the values returned by the block. + * See also Enumerable#collect</code>. + * + * a = [ "a", "b", "c", "d" ] + * a.collect {|x| x + "!" } #=> ["a!", "b!", "c!", "d!"] + * a #=> ["a", "b", "c", "d"] + */ + static VALUE rb_ary_collect(ary) VALUE ary; @@ -1205,6 +1646,20 @@ rb_ary_collect(ary) return collect; } +/* + * call-seq: + * array.collect! {|obj} ...} => array + * array.map! {|obj} ...} => array + * + * Invokes the block once for each element of _self_self, replacing the + * element with the value returned by _block_. + * See also Enumerable.collect. + * + * a = [ "a", "b", "c", "d" ] + * a.collect! {|x| x + "!" } + * a #=> [ "a!", "b!", "c!", "d!" ] + */ + static VALUE rb_ary_collect_bang(ary) VALUE ary; @@ -1251,6 +1706,21 @@ rb_values_at(obj, olen, argc, argv, func) return result; } +/* + * call-seq: + * array.values_at(selector,... ) => an_array + * Returns an array containing the elements in + * _self_ corresponding to the given selector(s). The selectors + * may be either integer indices or ranges. + * See also </code>.select<code>. + * + * a = %w{ a b c d e f } + * a.values_at(1, 3, 5) + * a.values_at(1, 3, 5, 7) + * a.values_at(-1, -3, -5, -7) + * a.values_at(1..3, 2...5) + */ + static VALUE rb_ary_values_at(argc, argv, ary) int argc; @@ -1260,6 +1730,21 @@ rb_ary_values_at(argc, argv, ary) return rb_values_at(ary, RARRAY(ary)->len, argc, argv, rb_ary_entry); } +/* + * call-seq: + * array.select {|i| block } -> an_array + * + * Invokes the block passing in successive elements from <i>arr</i>, + * returning an array containing those elements for which the block + * returns a true value (equivalent to <code>Enumerable#select</code>). + * + * a = %w{ a b c d e f } + * a.select(1, 3, 5) #=> ["b", "d", "f"] + * a.select(1, 3, 5, 7) #=> ["b", "d", "f", nil] + * a.select(-1, -3, -5, -7) #=> ["f", "d", "b", nil] + * a.select {|v| v =~ /[aeiou]/} #=> ["a", "e"] + */ + static VALUE rb_ary_select(argc, argv, ary) int argc; @@ -1281,6 +1766,23 @@ rb_ary_select(argc, argv, ary) return result; } +/* + * call-seq: + * array.delete(obj) => obj or nil + * array.delete(obj) {| | block } => obj or nil + * + * Deletes items from <i>self</i> that are equal to <i>obj</i>. If + * the item is not found, returns <code>nil</code>. If the optional + * code block is given, returns the result of <i>block</i> if the item + * is not found. + * + * a = [ "a", "b", "b", "b", "c" ] + * a.delete("b") #=> "b" + * a #=> ["a", "c"] + * a.delete("z") #=> nil + * a.delete("z") { "not found" } #=> "not found" + */ + VALUE rb_ary_delete(ary, item) VALUE ary; @@ -1337,6 +1839,20 @@ rb_ary_delete_at(ary, pos) return del; } +/* + * call-seq: + * array.delete_at(index) -> obj or nil + * + * Deletes the element at the specified index, returning that element, + * or <code>nil</code> if the index is out of range. See also + * <code>Array#slice!</code>. + * + * a = %w( ant bat cat dog ) + * a.delete_at(2) #=> "cat" + * a #=> ["ant", "bat", "dog"] + * a.delete_at(99) #=> nil + */ + static VALUE rb_ary_delete_at_m(ary, pos) VALUE ary, pos; @@ -1344,6 +1860,31 @@ rb_ary_delete_at_m(ary, pos) return rb_ary_delete_at(ary, NUM2LONG(pos)); } +/* + * call-seq: + * array.slice!(int) => obj or nil + * array.slice!(start, length) => sub_array or nil + * array.slice!(range) => sub_array or nil + * + * Deletes the element(s) given by an index (optionally with a length) + * or by a range. Returns the deleted object, subarray, or + * <code>nil</code> if the index is out of range. Equivalent to: + * + * def slice!(*args) + * result = self[*args] + * self[*args] = nil + * result + * end + * + * a = [ "a", "b", "c" ] + * a.slice!(1) #=> "b" + * a #=> ["a", "c"] + * a.slice!(-1) #=> "c" + * a #=> ["a"] + * a.slice!(100) #=> nil + * a #=> ["a"] + */ + static VALUE rb_ary_slice_bang(argc, argv, ary) int argc; @@ -1373,6 +1914,16 @@ rb_ary_slice_bang(argc, argv, ary) return rb_ary_delete_at(ary, NUM2LONG(arg1)); } +/* + * call-seq: + * array.reject! {| | block } -> array or nil + * + * Equivalent to <code>Array#delete_if</code>, deleting elements from + * _self_ for which the block evaluates to true, but returns + * <code>nil</code> if no changes were made. Also see + * <code>Enumerable#reject</code>. + */ + static VALUE rb_ary_reject_bang(ary) VALUE ary; @@ -1393,6 +1944,14 @@ rb_ary_reject_bang(ary) return ary; } +/* + * call-seq: + * arr.reject {|item| block } -> an_array + * + * Returns a new array containing the items in _self_ + * for which the block is not true. + */ + static VALUE rb_ary_reject(ary) VALUE ary; @@ -1402,6 +1961,17 @@ rb_ary_reject(ary) return ary; } +/* + * call-seq: + * array.delete_if {|item| block } -> array + * + * Deletes every element of <i>self</i> for which <i>block</i> evaluates + * to <code>true</code>. + * + * a = [ "a", "b", "c" ] + * a.delete_if {|x| x >= "b" } #=> ["a"] + */ + static VALUE rb_ary_delete_if(ary) VALUE ary; @@ -1410,6 +1980,28 @@ rb_ary_delete_if(ary) return ary; } +/* + * call-seq: + * array.zip(arg, ...) -> an_array + * array.zip(arg, ...) {| arr | block } -> nil + * + * Converts any arguments to arrays, then merges elements of + * <i>self</i> with corresponding elements from each argument. This + * generates a sequence of <code>self#size</code> <em>n</em>-element + * arrays, where <em>n</em> is one more that the count of arguments. If + * the size of any arguemnt is less than <code>enumObj#size</code>, + * <code>nil</code> values are supplied. If a block given, it is + * invoked for each output array, otherwise an array of arrays is + * returned. + * + * a = [ 4, 5, 6 ] + * b = [ 7, 8, 9 ] + * + * [1,2,3].zip(a, b) #=> [[1, 4, 7], [2, 5, 8], [3, 6, 9]] + * [1,2].zip(a,b) #=> [[1, 4, 7], [2, 5, 8]] + * a.zip([1,2],[8]) #=> [[4,1,8], [5,2,nil], [6,nil,nil]] + */ + static VALUE rb_ary_zip(argc, argv, ary) int argc; @@ -1449,6 +2041,17 @@ rb_ary_zip(argc, argv, ary) return result; } +/* + * call-seq: + * array.transpose -> an_array + * + * Assumes that <i>self</i> is an array of arrays and transposes the + * rows and columns. + * + * a = [[1,2], [3,4], [5,6]] + * a.transpose #=> [[1, 3, 5], [2, 4, 6]] + */ + static VALUE rb_ary_transpose(ary) VALUE ary; @@ -1478,6 +2081,18 @@ rb_ary_transpose(ary) return result; } +/* + * call-seq: + * array.replace(other_array) => array + * + * Replaces the contents of <i>self</i> with the contents of + * <i>other_array</i>, truncating or expanding if necessary. + * + * a = [ "a", "b", "c", "d", "e" ] + * a.replace([ "x", "y", "z" ]) #=> ["x", "y", "z"] + * a #=> ["x", "y", "z"] + */ + static VALUE rb_ary_replace(copy, orig) VALUE copy, orig; @@ -1496,6 +2111,15 @@ rb_ary_replace(copy, orig) return copy; } +/* + * call-seq: + * array.clear => array + * Removes all elements from _self_. + * + * a = [ "a", "b", "c", "d", "e" ] + * a.clear #=> [ ] + */ + VALUE rb_ary_clear(ary) VALUE ary; @@ -1509,6 +2133,30 @@ rb_ary_clear(ary) return ary; } +/* + * call-seq: + * array.fill(obj) -> array + * array.fill(obj, start [, length]) => array + * array.fill(obj, range ) => array + * array.fill {|i| block } => array + * array.fill(start [, length] ) {|i| block } => array + * array.fill(range) {|i| block } => array + * + * The first three forms set the selected elements of <i>self</i> (which + * may be the entire array) to <i>obj</i>. A <i>start</i> of + * <code>nil</code> is equivalent to zero. A <i>length</i> of + * <code>nil</code> is equivalent to <i>arr</i>.length. The last three + * forms fill the array with the value of the block. The block is + * passed the absolute index of each element to be filled. + * + * a = [ "a", "b", "c", "d" ] + * a.fill("x") #=> ["x", "x", "x", "x"] + * a.fill("z", 2, 2) #=> ["x", "x", "z", "z"] + * a.fill("y", 0..1) #=> ["y", "y", "z", "z"] + * a.fill {|i| i*i} #=> [0, 1, 4, 9] + * a.fill(-2) {|i| i*i*i} #=> [0, 1, 8, 27] + */ + static VALUE rb_ary_fill(argc, argv, ary) int argc; @@ -1580,6 +2228,16 @@ rb_ary_fill(argc, argv, ary) return ary; } +/* + * call-seq: + * array + other_array => an_array + * + * Concatenation---Returns a new array built by concatenating the + * two arrays together to produce a third array. + * + * [ 1, 2, 3 ] + [ 4, 5 ] #=> [ 1, 2, 3, 4, 5 ] + */ + VALUE rb_ary_plus(x, y) VALUE x, y; @@ -1596,6 +2254,15 @@ rb_ary_plus(x, y) return z; } +/* + * self.concat(other_array) => array + * + * Appends the elements in other_array to _self_. + * + * [ "a", "b" ].concat( ["c", "d"] ) #=> [ "a", "b", "c", "d" ] + */ + + VALUE rb_ary_concat(x, y) VALUE x, y; @@ -1607,6 +2274,21 @@ rb_ary_concat(x, y) return x; } + +/* + * call-seq: + * array * int => an_array + * array * str => a_string + * + * Repetition---With a String argument, equivalent to + * self.join(str). Otherwise, returns a new array + * built by concatenating the _int_ copies of _self_. + * + * + * [ 1, 2, 3 ] * 3 #=> [ 1, 2, 3, 1, 2, 3, 1, 2, 3 ] + * + */ + static VALUE rb_ary_times(ary, times) VALUE ary, times; @@ -1640,6 +2322,26 @@ rb_ary_times(ary, times) return ary2; } +/* + * call-seq: + * array.assoc(obj) => an_array or nil + * + * Searches through an array whose elements are also arrays + * comparing _obj_ with the first element of each contained array + * using obj.==. + * Returns the first contained array that matches (that + * is, the first assoc}iated array, + * or +nil+ if no match is found. + * See also Array.rassoc. + * + * s1 = [ "colors", "red", "blue", "green" ] + * s2 = [ "letters", "a", "b", "c" ] + * s3 = "foo" + * a = [ s1, s2, s3 ] + * a.assoc("letters") #=> [ "letters", "a", "b", "c" ] + * a.assoc("foo") #=> nil + */ + VALUE rb_ary_assoc(ary, key) VALUE ary, key; @@ -1659,6 +2361,20 @@ rb_ary_assoc(ary, key) return Qnil; } +/* + * call-seq: + * array.rassoc(key) -> an_array or nil + * + * Searches through the array whose elements are also arrays. Compares + * <em>key</em> with the second element of each contained array using + * <code>==</code>. Returns the first contained array that matches. See + * also <code>Array#assoc</code>. + * + * a = [ [ 1, "one"], [2, "two"], [3, "three"], ["ii", "two"] ] + * a.rassoc("two") #=> [2, "two"] + * a.rassoc("four") #=> nil + */ + VALUE rb_ary_rassoc(ary, value) VALUE ary, value; @@ -1678,6 +2394,20 @@ rb_ary_rassoc(ary, value) return Qnil; } +/* + * call-seq: + * array == other_array => bool + * + * Equality---Two arrays are equal if they contain the same number + * of elements and if each element is equal to (according to + * Object.==) the corresponding element in the other array. + * + * [ "a", "c" ] == [ "a", "c", 7 ] #=> false + * [ "a", "c", 7 ] == [ "a", "c", 7 ] #=> true + * [ "a", "c", 7 ] == [ "a", "d", "f" ] #=> false + * + */ + static VALUE rb_ary_equal(ary1, ary2) VALUE ary1, ary2; @@ -1731,6 +2461,19 @@ rb_ary_hash(ary) return LONG2FIX(h); } +/* + * call-seq: + * array.include?(obj) => true or false + * + * Returns <code>true</code> if the given object is present in + * <i>self</i> (that is, if any object <code>==</code> <i>anObject</i>), + * <code>false</code> otherwise. + * + * a = [ "a", "b", "c" ] + * a.include?("b") #=> true + * a.include?("z") #=> false + */ + VALUE rb_ary_includes(ary, item) VALUE ary; @@ -1746,6 +2489,27 @@ rb_ary_includes(ary, item) return Qfalse; } + +/* + * call-seq: + * array <=> other_array => -1, 0, +1 + * + * Comparison---Returns an integer (-1, 0, + * or +1) if this array is less than, equal to, or greater than + * other_array. Each object in each array is compared + * (using <=>). If any value isn't + * equal, then that inequality is the return value. If all the + * values found are equal, then the return is based on a + * comparison of the array lengths. Thus, two arrays are + * ``equal'' according to Array.<=> if and only if they have + * the same length and the value of each element is equal to the + * value of the corresponding element in the other array. + * + * [ "a", "a", "c" ] <=> [ "a", "b", "c" ] #=> -1 + * [ 1, 2, 3, 4, 5, 6 ] <=> [ 1, 2 ] #=> +1 + * + */ + VALUE rb_ary_cmp(ary1, ary2) VALUE ary1, ary2; @@ -1787,6 +2551,18 @@ ary_make_hash(ary1, ary2) return hash; } +/* + * call-seq: + * array - other_array => an_array + * + * Array Difference---Returns a new array that is a copy of + * the original array, removing any items that also appear in + * other_array. (If you need set-like behavior, see the + * library class Set.) + * + * [ 1, 1, 2, 2, 3, 3, 4, 5 ] - [ 1, 2, 4 ] #=> [ 3, 3, 5 ] + */ + static VALUE rb_ary_diff(ary1, ary2) VALUE ary1, ary2; @@ -1804,6 +2580,17 @@ rb_ary_diff(ary1, ary2) return ary3; } +/* + * call-seq: + * array & other_array + * + * Set Intersection---Returns a new array + * containing elements common to the two arrays, with no duplicates. + * + * [ 1, 1, 3, 5 ] & [ 1, 2, 3 ] #=> [ 1, 3 ] + */ + + static VALUE rb_ary_and(ary1, ary2) VALUE ary1, ary2; @@ -1826,6 +2613,17 @@ rb_ary_and(ary1, ary2) return ary3; } +/* + * call-seq: + * array | other_array => an_array + * + * Set Union---Returns a new array by joining this array with + * other_array, removing duplicates. + * + * [ "a", "b", "c" ] | [ "c", "d", "a" ] + * #=> [ "a", "b", "c", "d" ] + */ + static VALUE rb_ary_or(ary1, ary2) VALUE ary1, ary2; @@ -1853,6 +2651,20 @@ rb_ary_or(ary1, ary2) return ary3; } +/* + * call-seq: + * array.uniq! => array or nil + * + * Removes duplicate elements from _self_. + * Returns <code>nil</code> if no changes are made (that is, no + * duplicates are found). + * + * a = [ "a", "a", "b", "b", "c" ] + * a.uniq! #=> ["a", "b", "c"] + * b = [ "a", "b", "c" ] + * b.uniq! #=> nil + */ + static VALUE rb_ary_uniq_bang(ary) VALUE ary; @@ -1881,6 +2693,16 @@ rb_ary_uniq_bang(ary) return ary; } +/* + * call-seq: + * array.uniq => an_array + * + * Returns a new array by removing duplicate values in <i>self</i>. + * + * a = [ "a", "a", "b", "b", "c" ] + * a.uniq #=> ["a", "b", "c"] + */ + static VALUE rb_ary_uniq(ary) VALUE ary; @@ -1890,6 +2712,16 @@ rb_ary_uniq(ary) return ary; } +/* + * call-seq: + * array.compact! => array or nil + * + * Removes +nil+ elements from array. + * Returns +niL+ if no changes were made. + * [ "a", nil, "b", nil, "c" ].compact! #=> [ "a", "b", "c" ] + * [ "a", "b", "c" ].compact! #=> nil + */ + static VALUE rb_ary_compact_bang(ary) VALUE ary; @@ -1913,6 +2745,16 @@ rb_ary_compact_bang(ary) return ary; } +/* + * call-seq: + * array.compact => an_array + * + * Returns a copy of _self_ with all +nil+ elements removed. + * + * [ "a", nil, "b", nil, "c", nil ].compact + * #=> [ "a", "b", "c" ] + */ + static VALUE rb_ary_compact(ary) VALUE ary; @@ -1922,6 +2764,16 @@ rb_ary_compact(ary) return ary; } +/* + * call-seq: + * array.nitems -> int + * + * Returns the number of non-<code>nil</code> elements in _self_. + * May be zero. + * + * [ 1, nil, 3, nil, 5 ].nitems #=> 3 + */ + static VALUE rb_ary_nitems(ary) VALUE ary; @@ -1967,6 +2819,20 @@ flatten(ary, idx, ary2, memo) return lim - idx - 1; /* returns number of increased items */ } +/* + * call-seq: + * arr.flatten! -> arr or nil + * + * Flattens _self_ in place. + * Returns <code>nil</code> if no modifications were made (i.e., + * <i>arr</i> contains no subarrays.) + * + * a = [ 1, 2, [3, [4, 5] ] ] + * a.flatten! #=> [1, 2, 3, 4, 5] + * a.flatten! #=> nil + * a #=> [1, 2, 3, 4, 5] + */ + static VALUE rb_ary_flatten_bang(ary) VALUE ary; @@ -1992,6 +2858,20 @@ rb_ary_flatten_bang(ary) return ary; } +/* + * call-seq: + * array.flatten -> an_array + * + * Returns a new array that is a one-dimensional flattening of this + * array (recursively). That is, for every element that is an array, + * extract its elements into the new array. + * + * s = [ 1, 2, 3 ] #=> [1, 2, 3] + * t = [ 4, 5, 6, [7, 8] ] #=> [4, 5, 6, [7, 8]] + * a = [ s, t, 9, 10 ] #=> [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10] + * a.flatten #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10 + */ + static VALUE rb_ary_flatten(ary) VALUE ary; @@ -2001,6 +2881,14 @@ rb_ary_flatten(ary) return ary; } + +/* Arrays are ordered, integer-indexed collections of any object. + * Array indexing starts at 0, as in C or Java. A negative index is + * assumed to be relative to the end of the array---that is, an index of -1 + * indicates the last element of the array, -2 is the next to last + * element in the array, and so on. + */ + void Init_Array() { @@ -49,7 +49,9 @@ class RiDisplay ###################################################################### def display_params(method) + params = method.params + if params[0,1] == "(" if method.is_singleton params = method.full_name + params @@ -57,7 +59,7 @@ class RiDisplay params = method.name + params end end - @formatter.wrap(params) + params.split(/\n/).each {|p| @formatter.wrap(p) } end ###################################################################### @@ -107,10 +109,16 @@ def display_class_info(class_entry) end end - unless klass.method_list.empty? + unless klass.class_methods.empty? + @formatter.blankline + @formatter.wrap("Class methods:", "") + @formatter.wrap(klass.class_methods.map{|m| m.name}.sort.join(', ')) + end + + unless klass.instance_methods.empty? @formatter.blankline - @formatter.wrap("Methods:", "") - @formatter.wrap(klass.method_list.map{|m| m.name}.sort.join(', ')) + @formatter.wrap("Instance methods:", "") + @formatter.wrap(klass.instance_methods.map{|m| m.name}.sort.join(', ')) end unless klass.attributes.empty? diff --git a/lib/rdoc/generators/ri_generator.rb b/lib/rdoc/generators/ri_generator.rb index db86d744af..375c534923 100644 --- a/lib/rdoc/generators/ri_generator.rb +++ b/lib/rdoc/generators/ri_generator.rb @@ -100,8 +100,6 @@ module Generators cls_desc.superclass = cls.superclass cls_desc.comment = markup(cls.comment) - cls_desc.method_list = method_list(cls) - cls_desc.attributes =cls.attributes.sort.map do |a| RI::Attribute.new(a.name, a.rw, markup(a.comment)) end @@ -114,16 +112,23 @@ module Generators RI::IncludedModule.new(i.name) end - methods = method_list(cls) + class_methods, instance_methods = method_list(cls) - cls_desc.method_list = methods.map do |m| + cls_desc.class_methods = class_methods.map do |m| + RI::MethodSummary.new(m.name) + end + cls_desc.instance_methods = instance_methods.map do |m| RI::MethodSummary.new(m.name) end @ri_writer.remove_class(cls_desc) @ri_writer.add_class(cls_desc) - methods.each do |m| + class_methods.each do |m| + generate_method_info(cls_desc, m) + end + + instance_methods.each do |m| generate_method_info(cls_desc, m) end end @@ -155,7 +160,8 @@ module Generators private - # return a list of methods that we'll be documenting + # return a list of class and instance methods that we'll be + # documenting def method_list(cls) list = cls.method_list @@ -164,22 +170,37 @@ module Generators m.visibility == :public || m.force_documentation end end - - list.sort + + c = [] + i = [] + list.sort.each do |m| + if m.singleton + c << m + else + i << m + end + end + return c,i end def params_of(method) - p = method.params.gsub(/\s*\#.*/, '') - p = p.tr("\n", " ").squeeze(" ") - p = "(" + p + ")" unless p[0] == ?( - - if (block = method.block_params) - block.gsub!(/\s*\#.*/, '') - block = block.tr("\n", " ").squeeze(" ") - if block[0] == ?( - block.sub!(/^\(/, '').sub!(/\)/, '') + params = method.params || "" + + if params =~ /^!verb!(.*)/m + p = $1 + else + p = params.gsub(/\s*\#.*/, '') + p = p.tr("\n", " ").squeeze(" ") + p = "(" + p + ")" unless p[0] == ?( + + if (block = method.block_params) + block.gsub!(/\s*\#.*/, '') + block = block.tr("\n", " ").squeeze(" ") + if block[0] == ?( + block.sub!(/^\(/, '').sub!(/\)/, '') + end + p << " {|#{block.strip}| ...}" end - p << " {|#{block.strip}| ...}" end p end diff --git a/lib/rdoc/parsers/parse_c.rb b/lib/rdoc/parsers/parse_c.rb index 3d9d7a247f..3e8b48da34 100644 --- a/lib/rdoc/parsers/parse_c.rb +++ b/lib/rdoc/parsers/parse_c.rb @@ -153,7 +153,7 @@ module RDoc def remove_commented_out_lines @body.gsub!(%r{//.*rb_define_}, '//') end - + def handle_class_module(var_name, class_mod, class_name, parent, in_module) @known_classes[var_name] = class_name parent_name = @known_classes[parent] || parent @@ -162,7 +162,7 @@ module RDoc enclosure = @classes[in_module] unless enclosure $stderr.puts("Enclosing class/module '#{in_module}' for " + - class_mod + " #{class_name} not known") + "#{class_mod} #{class_name} not known") return end else @@ -175,10 +175,17 @@ module RDoc cm = enclosure.add_module(NormalModule, class_name) end cm.record_location(enclosure.toplevel) + find_class_comment(class_name, cm) @classes[var_name] = cm end + def find_class_comment(class_name, class_meth) + if @body =~ %r{((?>/\*.*?\*/\s+)) + (static\s+)?void\s+Init_#{class_name}\s*\(\)}xm + class_meth.comment = mangle_comment($1) + end + end def do_classes @body.scan(/(\w+)\s* = \s*rb_define_module\(\s*"(\w+)"\s*\)/mx) do @@ -224,14 +231,20 @@ module RDoc @body.scan(/rb_define_(singleton_method|method|module_function)\(\s*(\w+), \s*"([^"]+)", \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?, - \s*(-?\w+)\s*\)/xm) do + \s*(-?\w+)\s*\)/xm) do #" |type, var_name, meth_name, meth_body, param_count| + next if meth_name == "initialize_copy" + class_name = @known_classes[var_name] || var_name class_obj = @classes[var_name] if class_obj + if meth_name == "initialize" + meth_name = "new" + type = "singleton_method" + end meth_obj = AnyMethod.new("", meth_name) - meth_obj.singleton = type == "singleton_method" + meth_obj.singleton = type == "singleton_method" p_count = (Integer(param_count) rescue -1) @@ -265,7 +278,19 @@ module RDoc body_text = $& end - meth_obj.params = params + # If the comment block contains a section that looks like + # call-seq: + # Array.new + # Array.new(10) + # use it for the parameters + + if comment.sub!(/call-seq:(.*?)^\s*\*?\s*$/m, '') + seq = $1 + seq.gsub!(/^\s*\*\s*/, '') + meth_obj.params = "!verb!" + seq + end + +# meth_obj.params = params meth_obj.start_collecting_tokens meth_obj.add_token(RubyToken::Token.new(1,1).set_text(body_text)) meth_obj.comment = mangle_comment(comment) diff --git a/lib/rdoc/ri/ri_cache.rb b/lib/rdoc/ri/ri_cache.rb index 4ca976c4b9..da2a7e47ff 100644 --- a/lib/rdoc/ri/ri_cache.rb +++ b/lib/rdoc/ri/ri_cache.rb @@ -56,16 +56,16 @@ module RI # return the list of local methods matching name # We're split into two because we need distinct behavior # when called from the toplevel - def methods_matching(name) - local_methods_matching(name) + def methods_matching(name, is_class_method) + local_methods_matching(name, is_class_method) end # Find methods matching 'name' in ourselves and in # any classes we contain - def recursively_find_methods_matching(name) - res = local_methods_matching(name) + def recursively_find_methods_matching(name, is_class_method) + res = local_methods_matching(name, is_class_method) @inferior_classes.each do |c| - res.concat(c.recursively_find_methods_matching(name)) + res.concat(c.recursively_find_methods_matching(name, is_class_method)) end res end @@ -80,10 +80,19 @@ module RI private - # Return a list of all our methods matching a given string - def local_methods_matching(name) - @class_methods.find_all {|m| m.name[name] } + - @instance_methods.find_all {|m| m.name[name] } + # Return a list of all our methods matching a given string. + # Is +is_class_methods+ if 'nil', we don't care if the method + # is a class method or not, otherwise we only return + # those methods that match + def local_methods_matching(name, is_class_method) + list = case is_class_method + when nil then @class_methods + @instance + when true then @class_methods + when false then @instance_methods + else fail "Unknown is_class_method" + end + + list.find_all {|m| m.name[name]} end end @@ -91,8 +100,8 @@ module RI # for methods searches all classes, not just itself class TopLevelEntry < ClassEntry - def methods_matching(name) - res = recursively_find_methods_matching(name) + def methods_matching(name, is_class_method) + res = recursively_find_methods_matching(name, is_class_method) end def full_name diff --git a/lib/rdoc/ri/ri_descriptions.rb b/lib/rdoc/ri/ri_descriptions.rb index e80b4ebe05..f99905719b 100644 --- a/lib/rdoc/ri/ri_descriptions.rb +++ b/lib/rdoc/ri/ri_descriptions.rb @@ -1,5 +1,9 @@ require 'yaml' +# Descriptions are created by RDoc (in ri_generator) and +# written out in serialized form into the documentation +# tree. ri then reads these to generate the documentation + module RI Alias = Struct.new(:old_name, :new_name) AliasName = Struct.new(:name) @@ -35,7 +39,8 @@ module RI class ClassDescription < Description - attr_accessor :method_list + attr_accessor :class_methods + attr_accessor :instance_methods attr_accessor :attributes attr_accessor :constants attr_accessor :superclass diff --git a/lib/rdoc/ri/ri_formatter.rb b/lib/rdoc/ri/ri_formatter.rb index 052ac87906..1e70529bfe 100644 --- a/lib/rdoc/ri/ri_formatter.rb +++ b/lib/rdoc/ri/ri_formatter.rb @@ -55,7 +55,7 @@ module RI txt. gsub(%r{<tt>(.*?)</tt>}) { "+#$1+" } . gsub(%r{<b>(.*?)</b>}) { "*#$1*" } . - gsub(%r{<i>(.*?)</i>}) { "_#$1_" } . + gsub(%r{<em>(.*?)</em>}) { "_#$1_" } . gsub(/>/, '>'). gsub(/</, '<'). gsub(/"/, '"'). diff --git a/lib/rdoc/ri/ri_reader.rb b/lib/rdoc/ri/ri_reader.rb index f7e9e3074c..eb56d654fb 100644 --- a/lib/rdoc/ri/ri_reader.rb +++ b/lib/rdoc/ri/ri_reader.rb @@ -24,7 +24,7 @@ module RI def find_methods(name, is_class_method, namespaces) result = [] namespaces.each do |ns| - result.concat ns.methods_matching(name) + result.concat ns.methods_matching(name, is_class_method) end result end diff --git a/lib/rdoc/ri/ri_util.rb b/lib/rdoc/ri/ri_util.rb index 07f79b1d62..5d14650fac 100644 --- a/lib/rdoc/ri/ri_util.rb +++ b/lib/rdoc/ri/ri_util.rb @@ -9,6 +9,8 @@ class NameDescriptor attr_reader :class_names attr_reader :method_name + + # true and false have the obvious meaning. nil means we don't care attr_reader :is_class_method # arg may be @@ -25,9 +27,9 @@ class NameDescriptor def initialize(arg) @class_names = [] - separator = "." + separator = nil - tokens = arg.split(/\b/) + tokens = arg.split(/(\.|::|#)/) # Skip leading '::', '#' or '.', but remember it might # be a method name qualifier @@ -57,7 +59,9 @@ class NameDescriptor if @method_name =~ /::|\.|#/ or !tokens.empty? raise RiError.new("Bad argument: #{arg}") end - @is_class_method = separator == "::" + if separator + @is_class_method = separator == "::" + end end end end diff --git a/lib/rdoc/ri/ri_writer.rb b/lib/rdoc/ri/ri_writer.rb index 072b3acfea..70468cb1f5 100644 --- a/lib/rdoc/ri/ri_writer.rb +++ b/lib/rdoc/ri/ri_writer.rb @@ -28,7 +28,7 @@ module RI def add_method(class_desc, method_desc) dir = path_to_dir(class_desc.full_name) meth_file_name = File.join(dir, method_desc.name) - if method_desc.is_class_method + if method_desc.is_singleton meth_file_name += "-c.yaml" else meth_file_name += "-i.yaml" |