owned this note
owned this note
Published
Linked with GitHub
# Nerima.rb\#1
https://docs.ruby-lang.org/ja/2.6.0/class/String.html
演算子の名前を列挙してるサイト
https://ruby-operators.herokuapp.com/rose_memoization
### %
[sprintf](https://docs.ruby-lang.org/ja/2.6.0/method/Kernel/m/sprintf.html)と同じ
### *
- 文字数をオーバーフロー(水増し)させたいときに使う
```ruby
p "abc" * 0 # => '' 使えそう
p "abc" * -2 # => ArgumentError: negative argument
p "ああああああああ" * 0.5 # => '' 少数与えたらエラーにしたほうがよいのでは?
p "ああああああああ" * 2.5 # 切り捨て扱い
```
```ruby
def *(num)
num = Rubinius::Type.coerce_to(num, Integer, :to_int) unless num.kind_of? Integer
if num.kind_of? Bignum
raise RangeError, "bignum too big to convert into `long' (#{num})"
end
if num < 0
raise ArgumentError, "unable to multiple negative times (#{num})"
end
str = self.class.pattern num * @num_bytes, self
return str
end
```
to_intでサーチした結果
https://docs.ruby-lang.org/ja/search/version:2.5.0/query:to_int/
[to_i vs to_int]( http://www.rubyfleebie.com/2007/04/05/to_i-vs-to_int/)の記事
Stringクラスにto_intは生えていない
to_intが生えているクラスは数値っぽいクラス
![](https://i.imgur.com/rOL5XZ3.png)
```
irb(main):001:0> "1".to_i
=> 1
irb(main):002:0> "1".to_int
Traceback (most recent call last):
4: from /Users/hayashiyoshino/.rbenv/versions/2.6.1/bin/irb:23:in `<main>'
3: from /Users/hayashiyoshino/.rbenv/versions/2.6.1/bin/irb:23:in `load'
2: from /Users/hayashiyoshino/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/irb-1.0.0/exe/irb:11:in `<top (required)>'
1: from (irb):2
NoMethodError (undefined method `to_int' for "1":String)
Did you mean? to_i
taint
```
### +
文字列同士を連結して、新しい文字列として返す(重い)
https://docs.ruby-lang.org/ja/2.6.0/method/String/i/=2b.html
```ruby
def +(other)
other = StringValue(other)
Rubinius::Type.compatible_encoding self, other
String.new(self) << other
end
```
- Rubyの世界だとオブジェクトの生成は遅さの原因になる
- 結合に比べて生成は重い
### +self
https://docs.ruby-lang.org/ja/2.6.0/method/String/i/=2b=40.html
Frozenでない文字列を返す。
`+=`より`<<`のほうが高速なので`<<`を使いたいが、`frozen_string_literal`が効いているので使えないときとかに使うのかなあ。
使い所
```
# frozen_string_literal: true
```
しているとき、文字列が必ずイミュータルになるので、
文字列の頭に+をつけると解凍(元の文字列をコピー)することができて便利
https://dev.to/adamlombard/easy-ruby-plus-equals--vs-shovel--3pfj
### -self
↑の逆
https://docs.ruby-lang.org/ja/2.6.0/method/String/i/=2d=40.html
String+@とString-@は k0kubunさんのこの記事が詳しい
https://qiita.com/k0kubun/items/1c3e605645ba5ff683a1
### <<
concatと一緒
文字列に別の文字列を結合する
`<<` => 元のオブジェクトを変更する(破壊的変更)
`+` => 新しいオブジェクトを返す(非破壊的変更)
```ruby
def <<(other)
Rubinius.check_frozen
unless other.kind_of? String
if other.kind_of? Integer
if encoding == Encoding::US_ASCII and other >= 128 and other < 256
force_encoding(Encoding::ASCII_8BIT)
end
other = other.chr(encoding)
else
other = StringValue(other)
end
end
Rubinius::Type.infect(self, other)
append(other)
end
```
`encoding == Encoding::US_ASCII and other >= 128 and other < 256`に該当する数値を引数に取る場合は勝手にエンコードされる
[アスキーコード対応表](http://www12.plala.or.jp/mz80k2/electronics/ascii/ascii.html)
### <=>
<=>を実装した自作のクラスでもsortが使えるようになる
```ruby
irb(main):003:0> %w(Bob Dave Alice Chris).sort
=> ["Alice", "Bob", "Chris", "Dave"]
```
[comaparableモジュール](https://docs.ruby-lang.org/ja/2.5.0/class/Comparable.html)
```ruby
irb(main):004:0> Human = Struct.new(:name, :age)
=> Human
irb(main):005:0> alice = Human.new('alice', 30)
=> #<struct Human name="alice", age=30>
irb(main):006:0> bob = Human.new('bob', 25)
=> #<struct Human name="bob", age=25>
irb(main):007:0> [alice, bob].sort
Traceback (most recent call last):
5: from /Users/okuramasafumi/.rubies/ruby-2.6.1/bin/irb:23:in `<main>'
4: from /Users/okuramasafumi/.rubies/ruby-2.6.1/bin/irb:23:in `load'
3: from /Users/okuramasafumi/.rubies/ruby-2.6.1/lib/ruby/gems/2.6.0/gems/irb-1.0.0/exe/irb:11:in `<top (required)>'
2: from (irb):7
1: from (irb):7:in `sort'
ArgumentError (comparison of Human with Human failed)
```
```ruby
irb(main):008:0> Human = Struct.new(:name, :age) do
irb(main):009:1* def <=>(other)
irb(main):010:2> name <=> other.name
irb(main):011:2> end
irb(main):012:1> end
irb(main):013:0> alice = Human.new('alice', 30)
=> #<struct Human name="alice", age=30>
irb(main):014:0> bob = Human.new('bob', 25)
=> #<struct Human name="bob", age=25>
irb(main):015:0> [alice, bob].sort
=> [#<struct Human name="alice", age=30>, #<struct Human name="bob", age=25>]
```
[Structクラス](https://docs.ruby-lang.org/ja/latest/class/Struct.html)
<=>を書く+Comparableをincludeすると`<` `>` `==` が使えるようになる
ex) eachとEnumerableの関係
### ==, ===
https://docs.ruby-lang.org/ja/2.6.0/method/String/i/=3d=3d.html
引数がStringではないときの挙動が面白い。
#to_sと#to_str
#to_strはstringっぽいもの
Stringにおいては===は==のエイリアス
### =~
https://docs.ruby-lang.org/ja/2.6.0/method/String/i/=3d=7e.html
正規表現とのマッチ。
```
'string' =~ /(.)(.)(.)/
# => $1 = 's', $2 = 't', $3 = 'r'
```
組み込み変数を使わない場合はmatch?のほうが速い
るりまにそのことを書いてもいいかも
### []
https://docs.ruby-lang.org/ja/2.6.0/method/String/i/=5b=5d.html
終端なしrangeも使えた!
```ruby
2.6.2 pry(main)> 'string'[1..]
"tring"
```
```ruby
irb(main):003:0> "string"["str"]
=> "str"
irb(main):004:0> "string"[1, 2]
=> "tr"
irb(main):005:0> "string"[/(.)(.)/,1]
=> "s"
irb(main):006:0> "string"[/(.)(.)/,2]
=> "t"
irb(main):008:0> "string"[/(.)(.)/,3]
=> nil
irb(main):007:0> $~
=> #<MatchData "st" 1:"s" 2:"t">
```
### []=
指定したindexの位置にある文字列を置き換える
破壊的に置き換える
```ruby
buf = "string"
buf[1] = "!!"
p buf # => "s!!ring"
buf = "string"
buf[1, 4] = "!!"
p buf # => "s!!g"
```
第二引数に0を指定すると挿入になる
```ruby
buf = "string"
buf[1, 0] = "!!"
p buf # => "s!!tring"
```
挿入するときは[insert](http://docs.ruby-lang.org/ja/2.6.0/method/String/i/insert.html)が直感的
```ruby
buf = "def exec(cmd)"
buf[/def\s+(\w+)/, 1] = "preprocess"
p buf # => "def preprocess(cmd)"
```
置き換え機能は`sub!`で代用できる(けどこっちの方が速い)[sub!](https://docs.ruby-lang.org/ja/latest/method/String/i/sub=21.html)
挿入機能は`insert`で代用できる
ベンチマーク結果:
```ruby
require 'benchmark'
Benchmark.bm do |x|
x.report { 1000000.times { str = 'string' ; str.sub!(/ri/, '!!') } }
x.report { 1000000.times { str = 'string' ; str[/ri/] = '!!' } }
end
# => user system total real
# => 0.409844 0.002977 0.412821 ( 0.416889)
# => 0.337315 0.002956 0.340271 ( 0.343986)
```
### ascii_only?
https://docs.ruby-lang.org/ja/2.6.0/class/String.html#I_ASCII_ONLY--3F
アスキー文字列ならtrue
### b
https://docs.ruby-lang.org/ja/2.6.0/class/String.html#I_B
ASCII-8BIT にした文字列の複製
```ruby
'abc123'.encoding # => #<Encoding:UTF-8>
'abc123'.b.encoding # => #<Encoding:ASCII-8BIT>
```
### bytes
https://docs.ruby-lang.org/ja/2.6.0/class/String.html#I_BYTES
寿司ビール問題
https://blog.kamipo.net/entry/2015/03/23/093052
```ruby
2.6.2 pry(main)> '🍣'.bytes
[
[0] 240,
[1] 159,
[2] 141,
[3] 163
]
```
```ruby
2.6.2 pry(main)> '🍺'.bytes
[
[0] 240,
[1] 159,
[2] 141,
[3] 186
]
```
### bytesize
https://docs.ruby-lang.org/ja/2.6.0/class/String.html#I_BYTESIZE
バイトサイズを返す
```ruby
2.6.2 pry(main)> '🍺'.bytesize
4
```
### byteslice
https://docs.ruby-lang.org/ja/2.6.0/method/String/i/byteslice.html
nth バイト目の文字を返す
```ruby
2.6.2 pry(main)> '🍺'.byteslice(0)
"\xF0"
2.6.2 pry(main)> '🍺'.byteslice(0, 2)
"\xF0\x9F"
2.6.2 pry(main)> '🍺'.byteslice(0..2)
"\xF0\x9F\x8D"
```
### capitalize / capitalize!
https://docs.ruby-lang.org/ja/2.6.0/method/String/i/capitalize.html
```ruby
p "beer".capitalize # => "Beer"
p "bEER".capitalize # => "Beer"
p "Beer".capitalize! # => "nil"
```
変更されない時はnilが返る(capitalize!でメソッドチェーンできない…!!) 例に説明を追記したい、PRチャンス!
(upcase!downcase!swapcase!も同じ)
```ruby
2.6.2 pry(main)> 'Beer'.capitalize.upcase
"BEER"
```
これはできた
### casecmp
https://docs.ruby-lang.org/ja/2.6.0/method/String/i/casecmp.html
`<=>`と同じ(ただし大文字小文字の違いを無視する)
`sort`とかで使うためのメソッド。
[Encoding#compatible?]のリンク切れ、PRチャンス!
### casecmp?
https://docs.ruby-lang.org/ja/2.6.0/method/String/i/casecmp=3f.html
↑で比較した真偽値を返す
文字列のエンコーディングが非互換の時は `nil` を返す
### center
https://docs.ruby-lang.org/ja/2.6.0/method/String/i/center.html
```ruby
p "foo".center(10) # => " foo "
p "foo".center(1, '!') # => "foo"
p "foo".center(10, "*") # => "***foo****"
```
```ruby
2.6.2 pry(main)> 'sushi'.center(10, '')
ArgumentError: zero width padding
```
### chars
https://docs.ruby-lang.org/ja/2.6.0/method/String/i/chars.html
`self.each_char.to_a` `self.split("")`と同じ
```ruby
2.6.2 pry(main)> 'abc'.chars.map { |char| char + '🍣' }.join
"a🍣b🍣c🍣"
```
### chomp
https://docs.ruby-lang.org/ja/2.6.0/class/String.html#I_CHOMP
改行文字を取り除きたいときに便利
```ruby
2.6.2 pry(main)> `pwd`
"/Users/🍣\n"
2.6.2 pry(main)> `pwd`.chomp
"/Users/🍣"
```
### chomp!
### chop
https://docs.ruby-lang.org/ja/2.6.0/method/String/i/chop.html
最後の文字を消して返すけど、最後に\r\nがある場合はそれだけ消して返す
```ruby
p "string\n".chop # => "string"
p "string\r\n".chop # => "string"
p "strin\n\r".chop # => "string\n"
p "string".chop # => "strin"
p "strin".chop # => "stri"
p "".chop # => ""
```
文頭・文末の\n\rを全消しの場合はstripを使う
\n\rを全消しの場合はdeleteを使う
### chop!
破壊的に変更かつ自身に変更がない場合はnilが返る
### chr
https://docs.ruby-lang.org/ja/2.6.0/class/String.html#I_CHR
最初の一文字を返す
```ruby
a = "abcde"
a.chr
```
### clear
https://docs.ruby-lang.org/ja/2.6.0/class/String.html#I_CLEAR
文字列を空文字にする(破壊的変更)
### codepoints
https://docs.ruby-lang.org/ja/2.6.0/class/String.html#I_CODEPOINTS
codepointとは、「文字を表す数字」
```ruby
"🍣".codepoints
=> [127843]
127843.to_s(16)
=> "1f363"
```
![](https://i.imgur.com/x5KhGMA.png)
### count
https://docs.ruby-lang.org/ja/2.6.0/class/String.html#I_COUNT
```ruby
2.6.2 pry(main)> 'aa'.count('a')
2
2.6.2 pry(main)> 'aa'.count
ArgumentError: wrong number of arguments (given 0, expected 1+)
2.6.2 pry(main)> 'hogehoge'.count('hoge')
8
```
`size` `count` `length`挙動が違う
Enumerableの`count`はブロック取れて便利
`'hogehoge'.count('hoge')`の挙動は`tr`と類似
`tr`は正規表現使えないが早い
`gsub`は正規表現使える
### to_sym
https://www.codecademy.com/en/forum_questions/512a675cf116c52d0d00674b
`to_sym`のエイリアスとして`intern`もある
### succ/next
```ruby
2.6.2 pry(main)> '1'.next
"2"
2.6.2 pry(main)> '🍣'.succ
"🍤"
irb(main):010:0> "㍻".succ
=> "㍼"
```
### partition
```ruby
2.6.2 pry(main)> 'RubyOnRailsOnRails'.partition('On')
[
[0] "Ruby",
[1] "On",
[2] "RailsOnRails"
]
```
### scan
```ruby
2.6.2 pry(main)> 'foobar'.scan(/../)
[
[0] "fo",
[1] "ob",
[2] "ar"
]
2.6.2 pry(main)> 'this is a string'.scan(/\w+/)
[
[0] "this",
[1] "is",
[2] "a",
[3] "string"
]
```
[Rubular](https://rubular.com/)
`scan`と`chars`単語だけをとりたいとき`scan`が便利
### upto
https://docs.ruby-lang.org/ja/2.6.0/class/String.html#I_UPTO
```ruby
2.6.2 pry(main)> '㍻'.upto('㍾') { |str| p str }
"㍻"
"㍼"
"㍽"
"㍾"
```
### unicode_normalize
```ruby
irb(main):045:0> "㈱".unicode_normalize(:nfkd)
=> "(株)"
irb(main):046:0> "㍻".unicode_normalize(:nfkd)
=> "平成"
irb(main):047:0> "㍾".succ
=> "㍿"
irb(main):048:0> "㍾".succ.unicode_normalize(:nfkd)
=> "株式会社"
```
### start_with?
```ruby
"string".start_with?("s")
=> true
"string".start_with?("b")
=> false
```
### end_with?
```ruby
"string".end_with?("g")
=> true
"string".end_with?("b")
=> false
```
### sum
```ruby
"(株)".sum
=> 540
"株".sum
=> 560
```
### squeeze
```ruby
"aaaaaaaaabbbbbbbbbaaaaaaaa".squeeze
=> aba
```