#きっかけ
さきほど
hoge = [1, 2, 2, 3, 3, 4, 5, 6, 5, 4]
hoge.group_by{|i| i}.reject{|k,v| v.size == 1}.keys
#=> [2, 3, 4, 5]
[[Ruby]重複している値の扱い方 - Qiita](http://qiita.com/seiya1121/items/6c32c06313c8b316f9b3)
というのを読みました。
~~DRY を大原則としていたい~~私としては
>group_by{|i| i}
をなんとかできないのかと考えたのですが、ムリでした。
##補足:DRY とは →OAOO とは
>情報システムの構成や構築手法についての原則の一つで、同じ意味や機能を持つ情報やデータを複数の場所に重複して置くことをなるべく避けるべきとする考え方。
複数の場所に同じ情報が置かれていると変更時に整合性が取れなくなる危険性が高まるため、一箇所で管理して必ずそこから参照するようにすべきとする原則である。
転じて、プログラムコード中で同じ(ような)動作をするコードを何度も書かずに、一度書いたものを再利用するようにすべきとする意味で用いられることもあるが、 **こちらは本来は“Once and Only Once”(OAOO)原則と呼ばれるもの** である。
[DRY原則とは 【 Don't Repeat Yourself 】 - 意味/解説/説明/定義 : IT用語辞典](http://e-words.jp/w/DRYE58E9FE58987.html)
…うわ、今の今まで勘違いしてたorz OAOOだそうです\_φ(・\_・
#モンキーパッチ
オブジェクトに対して何もせずに自分自身を返すメソッドがあればいいのに…と思ったので、作りました。作ったというのもおこがましいほどのスクリプト。
```ruby
class Object
def self
self
end
end
これで望み通りの表記にできます!
hoge = [1, 2, 2, 3, 3, 4, 5, 6, 5, 4]
hoge.group_by(&:self).reject{ |k,v| v.size == 1 }.keys
#=> [2, 3, 4, 5]
やった\o/
#その他の例
"string".each_char.sort_by{ |char| char }
#=> ["g", "i", "n", "r", "s", "t"]
"string".each_char.sort_by(&:self)
#=> ["g", "i", "n", "r", "s", "t"]
"string".each_char.map{ |char| char }
#=> ["s", "t", "r", "i", "n", "g"]
"string".each_char.map(&:self)
#=> ["s", "t", "r", "i", "n", "g"]
#self って予約語じゃね?やばくね?
予約語はクラス名、変数名などに用いることはできません。(中略)また、def のあとやメソッド呼び出しのピリオドのあとなど メソッド名であるとはっきり分かる場所ではメソッド名として用いることができます 。
るりま:字句構造
ということでレシーバがハッキリしていれば self メソッドを作っても/使っても大丈夫っぽいです。
#先人の教え
同じことを考えている方が(当たり前でしょうが)居られました。
やはり Object#tap
を思いつきますよね。
selfを返すメソッドといえば、思い付くのが「tap」なんですけど「tap」はブロックがないと
localJumpError: no block given
(中略)なんでブロック必須なんだろ?? ブロックがない時はselfを返してくれればいいのに!
class Object
def tap
block_given? ? super : self
end
end
>[Rubyでselfを返すメソッドってあったっけ? - Qiita](http://qiita.com/masassiez/items/b88fa299a5e11680fff6)
#追記:`Kernel#itself` ができるそうです
コメント欄引用
>@niku
>つい先日コミットがあり 2.2 からは Kernel#itself というメソッドを利用できそうです.
いい話です^^
[Feature #6373: public #self - ruby-trunk - Ruby Issue Tracking System](https://bugs.ruby-lang.org/issues/6373)
を見てみると一昨年4月に `Object#self` が提案されていますね。
##9/30追記:2.2.0 preview1 に載ってきました
>いわゆる恒等関数と呼ばれる、自身 (self) をそのまま返すメソッド `Kernel#itself` が追加されました。
他の言語でも恒等関数が組み込みで存在する場合があり、`id` や `identity` などの名前で定義されていることが多いです。「 **名前重要!** 」の Ruby では恒等関数の導入案は以前からありましたが、名前がなかなか決まらなかったという経緯があります。今回は `itself` という名前に落ち着いたようで、ようやく導入されました。
[» Ruby 2.2.0 preview1: ついに来ました!恒等関数 Kernel#itself などなど TECHSCORE BLOG](http://www.techscore.com/blog/2014/09/29/ruby-2-2-0-preview1-%E3%81%A4%E3%81%84%E3%81%AB%E6%9D%A5%E3%81%BE%E3%81%97%E3%81%9F%EF%BC%81%E6%81%92%E7%AD%89%E9%96%A2%E6%95%B0-kernelitself-%E3%81%AA%E3%81%A9%E3%81%AA%E3%81%A9/)
#MRI 2.2 未満(正確には 2.1.2 以下)の為に itself gem を作ってみた
[riocampos/itself](https://github.com/riocampos/itself)
(2.1.3が出たから更新しなきゃ…)
$ gem install itself
で `Kernel#itself` が使えるようになります。
```ruby
[1, 2, 3, 4, 5, 1, 2, 2, 3].group_by(&:itself)
#=> {1=>[1, 1], 2=>[2, 2, 2], 3=>[3, 3], 4=>[4], 5=>[5]}
"string".each_char.sort_by(&:itself)
#=> ["g", "i", "n", "r", "s", "t"]