RubyのTips(java、.net 習得済向け)

# RubyのTips(java、.net 習得済向け)
他言語と比較してrubyの特徴的な部分に注視したTips
またRails関連については記述しない。


## 変数のスコープによる命名規則
* @変数名  … インスタンス変数 
* @@変数名 … クラス変数　　　　
* $変数名  … グローバル変数

ローカル変数も含めて各変数は宣言不要で、
利用可能なスコープの中で記述する。

下記ではメソッド内でローカル変数のように突然登場するが、
インスタンス変数として管理されている。

~~~ruby
class MyClass
 def method1
  return @val1
 end
end
~~~ 
 

## 文字列のシングルクォートとダブルクォート
* 'text' …　単純に文字列
* "text" …  式展開文字列（C#の $"text"と類似）  
"text#{val}" で変数「val」を文字列に設定できる。

ちなみに、バッククォート(\`)で囲んだ場合は、コマンドの実行となる。 
\`echo abc` → 標準出力の結果がリターンされる。 

## シンボルと文字列
* 文字列   … シングルクォート、ダブルクォートの範囲
* シンボル … コロン(:)で始まる識別子。実態は整数。  
ハッシュなどのキーワードに利用される。（シンボルを使うほうが文字列よりも処理コストが低くなる）

## キーワード引数のメソッド
~~~ ruby
method_name arg1:100, arg2:false
~~~
上記のように書かれている場合は、下記のように、
キーワード引数（引数名にコロン(:)付与）を持つメソッドの実行となる。

~~~ ruby
def method_name(arg1:, arg2:)
 …
end
~~~
C#にも括弧を付ければ同様の記述がある。
method_name(arg1:100, arg2:false);

rubyのメソッドの括弧は省略できるが
可読性から考えるとカッコ付で書くようにしたほうがよい。
(変数 or メソッドを判別しやすくなる）


## インスタンス内で自己を示す予約語
self
C#、javaのthisと同一。


## アクセサ(C#のプロパティ)

~~~ruby
class MyClass
 attr_accessor :item1
 attr_reader   :item2
 attr_writer   :item3
end

~~~
上記は下記の定義と同様になる。

~~~ruby
class MyClass
 def item1
  return @item1
 end 
 def item1=(val)
  @item1 = val
 end

 def item2
  return @item2
 end 

 def item3=(val)
  @item3 = val
 end
end

~~~

C#に直すと以下のイメージ

~~~C#
class MyClass{
 public object item1 {get;set;}
 public object item2 {get;}
 public object item3 {set;}
}
~~~

* attr_accessor
* attr_reader
* attr_writer   

これは予約語ではなく、メソッド名
引数のシンボル名を識別子として、@を付与したインスタンス変数
Getter、Setterを内部で作成している。
（クラスの動的作成）

C#でもMSILを利用すれば、
同じようにクラスに動的にプロパティを増やせたりする。

### アクセサを定義したときのselfと@(アットマーク)の違い
~~~ruby
class MyClass
 attr_accessor :item1
 
 # same constructor
 def initialize(arg)
    @item1 = arg
 end

 def sample        # output
   puts @item1     #-> "test"
   puts self.item1 #-> "test"
   
   puts @item2     #-> nil 
   puts self.item2 #-> undefined method `item2` 
 end 
end

ins = MyClass.new("test")
ins.sample()
~~~
@がインスタンスメンバへのアクセスなのに対して
selfは「item1」メソッドへのアクセスになる。

インスタンスメンバの場合、どこでも記述できるため
登場しなかったメンバを指定しても、新しく用意されるだけだが、
メソッドの場合は未定義エラーとなる。

タイプミスによる見つけにくいバグを避けるために、
可能な限りselfを利用したメソッドによるアクセスがよい。
(静的コードチェッカで見つけられるようになる？）

## メソッド名の命名文化
形式：snake_case
* bool値を返す … 最後に?を付与する。ex) exist_file?()
* 破壊的なメソッド … 最後に!を付与する ex) add_space!(text)


## クラスメソッドの定義
メソッド名の前に「クラス名.」を付けて作成することでクラスメソッドとなる。

~~~ruby
class MyClass
 def MyClass.sample 
   … 
 end 
end
~~~


## C#のLinq、Javaのstreamに対応する機能
|機能     |ruby            |C#                      |java                     |
|---      |---             |---                     |---                      |
|抽出     |select/find_all |Where                   |filter                   |
|射影     |map/collect     |Select                  |map                      |
|ソート   |find/detect     |FirstOrDefault          |sorted                   |
|2次ソート|sort/sort_by    |ThenBy/ThenByDescending |-                        |
|平坦化   |flat_map        |SelectMany              |flatMap                  |
|逆順     |reverse_each    |Reverse                 |-                        |
|         |---             |---                     |---                      |
|n件バイパス  |drop        |Skip                    |skip                     |
|条件バイパス |drop_while  |SkipWhile               |dropWhile(java9)         |
|n件取得      |take        |Take                    |limit                    |
|条件取得     |take_while  |TakeWhile               |takeWhile(java9)         |
|         |---             |---                     |---                      |
|連結     |(a, b).flat_map |Concat                  |concat                   |
|積集合   |Set#intersection/Set#&|Intersect               |-                        |
|和集合   |Set#union/Set#+       |Union                   |-                        |
|差集合   |Set#difference/Set#-  |Except                  |-                        |
|内部結合 |-                     |Join                    |-                        |
|外部結合 |-                     |GroupJoin               |-                        |
|         |---             |---                     |---                      |
|重複除外 |uniq            |Distinct                |distinct                 |
|畳込み   |inject          |Aggregate               |reduce                   |
|グループ |group_by        |GroupBy                 |Collectors.groupingBy    |
|平均     |-               |Average                 |IntStream.average/</br>Collectors.summmarizingXX |
|合計     |(inject(:+))    |Sum                     |IntStream.sum/</br>Collectors.summmarizingXX |
|件数     |count           |Count/LongCount         |count                    |
|最大     |max/max_by      |Max                     |max                      |
|最小     |min/min_by      |Min                     |min                      |
|先頭     |first           |First/FirstOrDefault    |findFirst                |
|終端     |last            |Last/LastOrDefault      |-                        |
|任意     |-               |-                       |findAny                  |
|1件      |one?            |Single/SingleOrDefault  |-                        |
|型一致取得    |grep          |OfType                       |-                        |
|インデックス  |at            |ElementAt/ElementAtOrDefault |-                        |
|空集合時の既定|-             |DefaultIfEmpty               |-                        |
|            |---             |---                     |---                      |
|全件一致    |all?            |All                     |allMatch                 |
|存在確認    |any?            |Any                     |-                        |
|対象存在確認|include?/member?|Contains                |-                        |
|1件以上一致 |any?            |Any                     |anyMatch                 |
|全件不一致  |-               |-                       |noneMatch                |
|            |---             |---                     |---                      |
|空集合作成  |-               |Empty                   |empty                    |
|範囲作成    |-               |Range                   |IntStream.range/rangeClosed |
|繰返し作成  |cycle           |Repeat                  |-                        |
|            |---             |---                     |---                      |
|2つのシーケンス    |zip         |Zip                      |zip                      |
|2つのシーケンス一致|-           |SequencialEqual          |-                        |
|列挙               |each        |ToList().ForEach         |forEach                  |