module RandomAccessible
- Author
-
Natsuki Kawai (natsuki.kawai@gmail.com)
- Copyright
-
Copyright 2011 Natsuki Kawai
- License
-
2-clause BSDL or Ruby’s
RandomAccessible
mixin provides all instance methods of Array
. Some methods are defined in RandomReadable
or RandomWritable
. The class must provide one or more methods from read-accessor group ([], at, read_access). The class must provide one or more methods from replace-accessor ([]=, replace_at, replace_access) and shrink-accessor (shrink) respectively. The class may provide insert-accessor (insert_access, insert_at
, insert) and delete-accessor (delete_access, delete_at
). The class may provide one size-provider (size, length). See the docment of RandomReadable
and RandomWritable
.
Private Class Methods
Define modifiers.
# File lib/random-accessible.rb, line 26 def self.define_modifying_method(*methods) methods.each do |method| modifier = method.to_s + '!' define_method modifier do |*args, &block| res = send(method, *args, &block) if self == res return nil else replace(res) return self end end end end
Public Instance Methods
Same as Array’s. See the docment of RandomReadable#collect.
# File lib/random-accessible.rb, line 57 def collect!(&block) if block.nil? return Enumerator.new(self, :collect!) else replace(collect(&block)) end end
Same as Array’s. This method raises NotImplementedError if the class provides no size-provider.
# File lib/random-accessible.rb, line 73 def delete(val, &block) deleted = 0 if method(:delete_at).owner == RandomAccessible size.times do |i| if at(i) == val deleted += 1 else replace_at(i - deleted, at(i)) end end shrink deleted else size.times do |i| if at(i) == val delete_at(i - deleted) deleted += 1 end end end if deleted > 0 return val elsif block.nil? return nil else return block.call end end
Same as Array’s. This method raises NotImplementedError if the class provides no size-provider and pos is negative. This method works without delete_access.
# File lib/random-accessible.rb, line 106 def delete_at(pos) if pos < 0 pos += size end if pos < 0 || (has_size? && size <= pos) return nil end res = self[pos] ((pos + 1)...size).each do |i| replace_at(i - 1, at(i)) end shrink 1 return res end
Same as Array’s. This method raises NotImplementedError if the class provides no size-provider.
# File lib/random-accessible.rb, line 125 def delete_if(&block) if block.nil? reject! else reject!(&block) return self end end
Fixed-number-argument version of insert(pos, *val). This method works without override of insert_access.
# File lib/random-accessible.rb, line 47 def insert_at(pos, val) expand 1 (pos...(size - 1)).reverse_each do |i| self[i + 1] = self[i] end self[pos] = val end
Same as Array’s. This method raises NotImplementedError if the class provides no size-provider.
# File lib/random-accessible.rb, line 162 def keep_if(&block) if block.nil? return Enumerator.new(self, :keep_if) else reject! do |el| !block.call(el) end end end
Same as Array’s. This method raises NotImplementedError if the class provides no size-provider.
RandomWritable#pop
# File lib/random-accessible.rb, line 175 def pop(*args) # Needs size. if args.size > 1 raise ArgumentError, "wrong number of arguments (#{args.size} for 0..1)" end res = nil if args.size == 0 unless empty? res = at(size - 1) super end else n = args[0] n = size if n > size res = self[(size - n)...size] super n end return res end
Same as Array’s. This method raises NotImplementedError if the class provides no size-provider.
# File lib/random-accessible.rb, line 137 def reject!(&block) if block.nil? return Enumerator.new(self, :reject!) else deleted = 0 size.times do |i| val = self[i] if block.call(val) deleted += 1 else self[i - deleted] = val end end if deleted > 0 shrink deleted return self else return nil end end end
Same as Array’s. This method raises NotImplementedError if the class provides no size-provider.
# File lib/random-accessible.rb, line 199 def reverse! # TODO: Optimize me. replace(reverse) end
Same as Array’s. This method raises NotImplementedError if the class provides no size-provider.
# File lib/random-accessible.rb, line 207 def rotate!(cnt = 1) # TODO: Optimize me. replace(rotate(cnt)) end
Same as Array’s. This method raises NotImplementedError if the class provides no size-provider.
RandomWritable#shift
# File lib/random-accessible.rb, line 217 def shift(*args) if args.size > 1 raise ArgumentError, "wrong number of arguments (#{args.size} for 0..1)" end if args.empty? res = self[0] super return res else n = args[0] res = self[0...n] super n return res end end
Same as Array’s. This method raises NotImplementedError if the class provides no size-provider.
# File lib/random-accessible.rb, line 237 def shuffle! # TODO: Optimize me. replace(shuffle) end
Same as Array’s. This method raises NotImplementedError if the class provides neither size-provider nor delete-accessor.
# File lib/random-accessible.rb, line 245 def slice!(*args) unless (1..2).include?(args.size) raise ArgumentError, "wrong number of arguments (#{args.size} for 1..2)" end if args.size == 2 || args[0].is_a?(Range) start = len = nil if args.size == 2 start = args[0] len = args[1] else range = args[0] start = range.first len = range.last - start len += 1 unless range.exclude_end? end res = self[*args] len.times do delete_at(start) end return res else pos = args[0].to_int if pos < 0 pos += size end if pos < 0 || size <= pos return nil else res = self[pos] delete_at(pos) return res end end end
Same as Array’s. This method raises NotImplementedError if the class provides no size-provider.
# File lib/random-accessible.rb, line 284 def sort!(&block) # TODO: Optimize me. replace(sort(&block)) end
Same as Array’s. This method raises NotImplementedError if the class provides no size-provider.
# File lib/random-accessible.rb, line 292 def sort_by!(&block) # TODO: Optimize me. if block.nil? return Enumerator.new(self, :sort_by!) else replace(sort_by(&block)) end end
Same as Array’s. This method raises NotImplementedError if the class provides neither size-provider nor insert-accessor.
# File lib/random-accessible.rb, line 304 def unshift(*obj) # TODO: Optimize me. insert(0, *obj) end