From: Simon Strandgaard Date: 2004-10-24T22:32:12+09:00 Subject: [rcr] String#first / String#last problem: I often use a range to extract the beginning/ending letters.. like this "string"[-4, 4] #-> "ring" It feels somewhat redundant that I have to type the length 2 times. A very simple operation that easily can confuse people if they are browsing through others code.. this is a place where one easily can introduce off-by-one errors. motivation: When looking at the Array class I see that it has #first and #last methods.. just for this purpose, to extract the sub-array either from the beginning or the ending. Why not also use #first and #last on String ? proposal: "ruby".first(2) #=> "ru" "ruby".last(3) #=> "uby" implementation: class String def first(n=nil) n ||= 1 raise TypeError, "cannot convert #{n.class} to Integer" unless n.kind_of? (Integer) raise ArgumentError, "negative string size" if n < 0 n = [n, self.size].min self[0, n] end def last(n=nil) n ||= 1 raise TypeError, "cannot convert #{n.class} to Integer" unless n.kind_of? (Integer) raise ArgumentError, "negative string size" if n < 0 n = [n, self.size].min self[-n, n] end end open questions: Some encodings has variable length chars, where a char may span between 1 and 5 bytes. This raises the question: how should the argument to #first be interpreted? should it interpret as bytes or chars? Is this a good or a bad proposal? -- Simon Strandgaard