lib/core/facets/indexable.rb in facets-2.1.3 vs lib/core/facets/indexable.rb in facets-2.2.0
- old
+ new
@@ -14,36 +14,48 @@
# just as #slice is an alias of #[]. #size of course simply
# returns the total length of the indexable object.
#
# AUTHORS:
#
-# CREDIT THomas Sawyer
+# - Thomas Sawyer
+# Indexable is a mixin that provides index based methods,
+# working soley with four methods: #index, #slice, #splice
+# and #size.
+#
+# These methods work in harmony. Where #index returns a
+# position of a given element, #slice returns elements
+# for given positions. #splice is like #slice but replaces
+# the given position with new values. This mehtod is not
+# part of ruby core, but it generally just an alias for #[]=,
+# just as #slice is an alias of #[]. #size of course simply
+# returns the total length of the indexable object.
+
module Indexable
# Like #first but returns the first element
# in a new array.
#
# [1,2,3].head #=> [1]
- #
+
def head
slice(0,1)
end
# Returns an array from second element to last element.
#
# [1,2,3].tail #=> [2,3]
- #
+
def tail
slice(1,length-1)
end
# Like #last, returning the last element
# in an array.
#
# [1,2,3].foot #=> [3]
- #
+
def foot
slice(-1,1)
end
# Returns an array of the first element upto,
@@ -52,10 +64,11 @@
# [1,2,3].body #=> [1,2]
#
#--
# Better name for this? (bulk, perhaps?)
#++
+
def body
slice(0,size-1)
end
# Returns the middle element of an array, or the element offset
@@ -69,10 +82,11 @@
# [1,2,3,4,5,6].mid(1) #=> 5
#
# In other words, If there are an even number of elements the
# higher-indexed of the two center elements is indexed as
# orgin (0).
+
def mid(offset=0)
slice((size / 2) + offset)
end
# Returns the middle element(s) of an array. Even-sized arrays,
@@ -81,10 +95,11 @@
#
# [1,2,3,4,5].middle #=> 3
# [1,2,3,4,5,6].middle #=> [3,4]
#
# In contrast to #mid which utilizes an offset.
+
def middle
if size % 2 == 0
slice( (size / 2) - 1, 2 )
#[slice((size / 2) - 1, 1), slice(size / 2, 1)]
else
@@ -94,11 +109,11 @@
# Fetch values from a start index thru an end index.
#
# [1,2,3,4,5].thru(0,2) #=> [1,2,3]
# [1,2,3,4,5].thru(2,4) #=> [3,4,5]
- #
+
def thru(from, to)
a = []
i = from
while i <= to
a << slice(i)
@@ -108,19 +123,19 @@
end
# Returns first _n_ elements.
#
# "Hello World".first(3) #=> "Hel"
- #
+
def first(n=1)
slice(0, n.to_i)
end
# Returns last _n_ elements.
#
# "Hello World".last(3) #=> "rld"
- #
+
def last(n=1)
n = n.to_i
return self if n > size
slice(-n, n) #slice(-n..-1)
end
@@ -128,33 +143,41 @@
# Change the first element.
#
# a = ["a","y","z"]
# a.first = "x"
# p a #=> ["x","y","z"]
- #
+
def first=(x)
splice(0,x)
end
# Change the last element.
#
# a = [1,2,5]
# a.last = 3
# p a #=> [1,2,3]
- #
+
def last=(x)
splice(-1,x)
end
# Remove and return the first element.
#
+ # a = [1,2,3]
+ # a.first! #=> 1
+ # a #=> [2,3]
+
def first!
splice(0)
end
# Remove and return the last element.
#
+ # a = [1,2,3]
+ # a.last! #=> 3
+ # a #=> [1,2]
+
def last!
splice(-1)
end
# A shorting of "ends at", returns the
@@ -162,33 +185,38 @@
# Returns nil if there are no elements.
#
# [1,2,3,4,5].ends #=> 4
#
# This nearly equivalent to +size - 1+.
+
def ends
return nil if size == 0
size - 1
end
# Returns the positive ordinal index given
# a cardinal position, 1 to n or -n to -1.
#
# [1,2,3,4,5].pos(1) #=> 0
# [1,2,3,4,5].pos(-1) #=> 4
- #
+
def pos(i)
if i > 0
return i - 1
else
size + i
end
end
- # TODO Remove Array#index_of when future Ruby adds block to #index.
+ # Returns the index of the first element to satisfy the block
+ # condition. This is simply #index with a block.
+ #
+ # [1,2,3,4].index_of { |e| e == 3 } #=> 2
+ # [1,2,3,4].index_of { |e| e > 3 } #=> 3
+ #
+ # TODO: Remove Array#index_of when Ruby 1.9 adds block to #index.
- # Allows block usage with index.
-
def index_of(obj=nil,&blk)
return index(obj) unless block_given?
i=0; i+=1 until yield(self[i])
return i
end
@@ -199,10 +227,10 @@
# If no elements are given, returns the range
# from first to last.
#
# ['a','b','c','d'].range #=> 0..3
# ['a','b','c','d'].range('b','d') #=> 1..2
- #
+
def range(a=nil,z=nil)
if !a
0..(size-1)
else
index(a)..index(z)