54267


Rubyで文字列末尾からn文字を取り出したいです

Ruby の String#slice は、第一引数に「文字列の長さ+1」を超える絶対値を持つ数値を渡すと nil を返却します  
そのため、安易に `str.slice(-n, -1)` としてしまうと nil が返却されてしまい、nil チェックなしに String
のメソッドを利用すると NoMethodError が発生してしまいます  
(n は必ず正の整数です)

Ruby では「文字列の末尾n文字を得る」という至極単純な操作を分岐なしに実現することは本当にできないのでしょうか?  
`str.slice(-n, -1) || ""` で限界なのでしょうか?


CC BY-SA 4.0
2019-04-17T11:25:10.113
54259
2019-04-18T09:59:46.913
9796
question
ruby
Rubyで文字列からn文字を分岐なく取り出すには


元の文字列を`str`、欲しい末尾からの文字数が`n`とした場合

[code]

    str.slice((str.length - n), n) || str
    
[/code]

という方法があるとおもいます。

`||`以降は、length < n の場合、全文字列を返すことで足りないけど、後ろから`n`文字は全文字列だよという感じで


CC BY-SA 4.0
2019-04-17T20:55:33.340
54267
2019-04-17T21:01:08.823
2019-04-17T21:01:08.823
14745
14745
54259
answer


もしかしたら、どなたかがシンプルで使いやすいイディオムを思いつくかもしれないですが、あなたがお書きになった

`str.slice(-n, -1) || ""`

で十分かと思います。

> 安易に str.slice(-n, -1) としてしまうと nil が返却されてしまい、nil チェックなしに String のメソッドを利用すると
> NoMethodError が発生してしまいます

とありますが、

<https://ruby-doc.org/core-2.2.0/String.html#method-i-slice>

に

> slice(start, length) → new_str or nil

と、ご存知の通り nil を返す仕様です。  
これを nil
ではなく空文字を返す仕様にする方法はないかということと同じことだと思います。そういったメソッドは無いので、既存の似たようなメソッド（今回はnilを返す）に空文字を返してくれといっても無理です。

ちなみに`Array`には`fetch`という該当するインデックスが無い場合、デフォルトの値を変わりに取得するメソッドがありますが、この`fetch`は範囲を指定することができないので、似ているがやはり違う用途となります。`fetch`と`slice`を参考にご自身で欲しいメソッドを作ったほうがよいかと考えます。


CC BY-SA 4.0
2019-04-17T22:44:42.260
54268
2019-04-17T22:44:42.260
9008
54259
answer


式展開すればnilの部分は空文字になりますのでお望みの結果が得られると思います。

[code]

    "#{str[-n..-1]}"
    
[/code]


CC BY-SA 4.0
2019-04-18T05:28:39.773
54272
2019-04-18T05:28:39.773
9608
54259
answer


他の皆様の回答を読んで、@gochoさんが本当に欲しいものが解らなくなったので、補足です。

以降の処理でn文字の文字列が必要で、後ろからn文字が意味を持つのであれば、

[code]

    str = " " * n + str
    lastn = str.slice((str.length - n), n)
    
[/code]

とすることで、長さが必ず`n`で、空白により右詰めの文字列を得る方法もあると思います。  
こうすると、`str`の内容が`""`でも`n`個の`"
"`が得られるので、以降の処理で`n`文字以上ある事が前提の場合、以降の処理で落ちない事が保証されます。


CC BY-SA 4.0
2019-04-18T09:59:46.913
54286
2019-04-18T09:59:46.913
14745
54259
answer