> first,lastに反対ではありませんが、str[-n..-1]ではどうでしょうか。

確かに、こちらの方が分かりやすいですね。

ただ、n > size のときに nil になってしまうので、
size を気にかけないといけないという問題があります。

(これは str[size - n, n] でも同様で、Array#last と同じ挙動にするには
最初のメールで挙げたように str[[size - n, 0].max, n] でないといけない)

しかし、そこまでの (size と n を気にせず末尾 n バイトを取得したいという)
需要があるかどうかは……うーん、レアなケースかもしれません。
自分でも、そのようなコードを書いた覚えはちょっとないです。


私の意見が分かりづらくなってしまいましたのでまとめますと、

* String#first や String#last が、String にとって
  不自然なメソッドであるとは思わない。
* String#first や String#last に対する需要は
  ゼロではないと思うが、Array よりは少ないであろう。
* n と size の大小関係を気にせず使えるのは便利そうである。
  ただし、そのようなケースがどれくらいあるかは不明。

といったところです。


ところで、これは String#first, String#last とは離れるのですが、
Array#[first..last] や String#[first..last] で、
first < -size の場合でも nil にしない、というのは考えられる話なのでしょうか?

last の方は、size - 1 < last でも nil にはなりませんよね。

irb(main):001:0> 'abcde'[0..99]
=> "abcde"
irb(main):002:0> 'abcde'[-100..-1]
=> nil

影響範囲が大きそうなので実際には変えられないとは思いますが、
可能性として伺ってみたいです。

-- 
Kouhei Yanagita <yanagi at shakenbu.org>