【Week 11】class, ruby_sixth



# はじめに

マルチスケールシミュレーション特論の講義メモです．講義メモのインデックスは[コチラ](<https://qiita.com/e79a93e5b7b1/items/d48ad7b8df544d737a78>)

今回の参考資料は[チャート式ruby-VI(hello class)](<https://qiita.com/daddygongon/items/969ad5112878f6dab844>)です．


# チャート式 Ruby

参照記事は[コチラ](<https://qiita.com/daddygongon/items/969ad5112878f6dab844>)


## class

今回は class について学んでいく．オブジェクト思考の考え方の肝となるポイントととして

-   capsulation(隠蔽)
-   inheritance(継承)
-   polymorphism(多形)

の 3 つが挙げられるが，method やclass は 1 つ目の隠蔽に属するらしい．


### hello class

以前作成した hello.rb を用いて class について学ぶ．

```ruby
def puts_hello name
  puts "Hello #{name}."
end

def gets_name
  name = ARGV[0] || 'world'
  return name
end

name = gets_name
puts_hello name
```

class を用いて main 関数自体を無くしてしまおうというのが魂胆である．

まずは Hello class を作成する．

```ruby
class Hello
  def puts_hello name
    puts "Hello #{name}."
  end

  def gets_name
    name = ARGV[0] || 'world'
    return name
  end
end

Hello.new
```

`Hello.new` は instance といって，これだけでは何も起きない．

ここで instance を作成した際に実行される initialize というメソッドを用いることで hello.rb 同等のプログラムを実装する．

```ruby
class Hello
  def initialize
    name = gets_name
    puts_hello name
  end

  def puts_hello name
    puts "Hello #{name}."
  end

  def gets_name
    name = ARGV[0] || 'world'
    return name
  end
end

Hello.new
```

少しずつスタイリッシュになってきた．ここで気になるのが initialize メソッドの変数 name .引数として渡すべきか，関数 puts\_hello 内で呼ぶべきか．

ここで class 特有の instance 変数が活躍する． `@name` とすることでオブジェクトが存在する限り instance 内で共有できる変数として扱うことができる．（ニュアンスはグローバル変数みたいな感じ，ニュアンスね．）

instance 変数を用いるとこんな感じ．

```ruby
class Hello
  def initialize
    @name = gets_name
    puts_hello
  end

  def puts_hello name
    puts "Hello #{@name}."
  end

  def gets_name
    name = ARGV[0] || 'world'
    return name
  end
end

Hello.new
```

実行してみると，

    > ruby hello_class.rb
    Hello world.
    > ruby hello_class.rb Rudy
    Hello Rudy.

class を用いて hello.rb 通りの出力が得られるプログラムを作成できた．


### method と object 指向

method と object 指向の違いについてこれまで意識したことがなかったので，これを機に学んでいく．

-   method: verb(subject, object)

-   object 指向: subject.verb(object)

確かに object 指向って後者のイメージ．

method 的なイメージは `関数名(必要とする変数)` のような感じだけど，object 指向では `対象の変数.関数名（必要なもの）` のようなイメージ．object 指向のほうがどの変数に対して働きかけているのかが理解しやすいのはこういうイメージからなのか．

とりあえず，講義資料どおり method ・ class の継承 ・ オーバーライドの書き方 3 通りを見てみる．

```ruby
require 'colorize'

# method
def hello(name)
  "Hello #{name}."
end

# inherited class
class Greeter < String
  def hello
    "Hello #{self}."
  end
end

# extend class
class String
  def hello
    "Hello #{self}."
  end
end

# method call
name = ARGV[0]
puts hello(name).green

# inherited class call
greeter = Greeter.new(ARGV[0])
puts greeter.hello.green

# extend class call, override
puts ARGV[0].hello.green
```

method や class の部分を比較するのもよいが，注目するポイントは呼び出し部分．method の手法はいつも通り変数に代入して，引数に受けわたしている．

class の継承ではどうだろうか．一度 instance を作成し，その時に値を保持している．美しい．

override ではそもそも instance すら作成されていない．そもそも String class の中に処理を置いてしまうという図々しさ．ある意味スタイリッシュ．

どれが良いかと言ったら間違いなく override でしょ．それは人の好みによるか．


### attr\_accessor

参照記事を読んでみたものの，イマイチよくわからなかった．

**実力不足．不甲斐なし．**


### 発展問題

**assert\_equalをclass化して，Integerに override しなさい．**

```org
- 3.assert_equal 3でtrueが返るようになります．
- selfで3とかが返るはず．
- moduleをincludeする方が筋が良さそうですが．．．自信ありません．
```

とのこと，面白そうなのでやってみた．

```ruby
require 'colorize'

class Integer
  def puts_vals(expected, result)
    puts "expected :: #{expected}"
    puts "result   :: #{result}"
  end

  def assert_equal(expected)
    puts_vals(expected, self)
    print  case expected == self
	   when true  ; "succeeded in #{__method__}.\n".green
	   when false ; "failed in #{__method__}.\n".red
    end
  end
end

puts 3.assert_equal 3
```

    > ruby assert_equal_class.rb
    expected :: 3
    result   :: 3
    succeeded in assert_equal.

できたっぽいね．今回でオブジェクト指向の良さが少しわかった気がする．


# Ruby 開発周辺情報

今回はチャート式 Ruby のみです．


# 次回の講義内容 <span class="timestamp-wrapper"><span class="timestamp">&lt;2020-12-16 Wed&gt;</span></span>

次回の講義は

-   [チャート式ruby-appendix-VI(thor, rubocop)](<https://qiita.com/daddygongon/items/19e58f757fab197bc347>)

だそうです．



------
 - **source** ~/grad_members_20f/members/e79a93e5b7b1/posts/class/c11_20201202.org