質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.07%

ruby プロを目指す人のためのruby入門

解決済

回答 2

投稿

  • 評価
  • クリップ 1
  • VIEW 1,133

kwtkwt

score 19

enterメソッドで駅名が一緒に保存される理由がわかりません。。。
よろしくお願いいたします。

class Gate
  STATIONS = [:umeda, :juso, :mikuni]
  FARES = [150, 190]

  def initialize(name)
    @name = name
  end

  def enter(ticket)
    ticket.stamp(@name)
  end

  def exit(ticket)
    fare = calc_fare(ticket)
    fare <= ticket.fare
  end

  def calc_fare(ticket)
    from = STATIONS.index(ticket.stamp_at)
    to = STATIONS.index(@name)
    distance = to - from
    FARES[distance - 1]
  end
end
class Ticket
  attr_reader :fare, :stamp_at

  def initialize(fare)
    @fare = fare
  end

  def stamp(name)
    @stamp_at = name
  end
end
require 'minitest/autorun'
require './lib/gate'
require './lib/ticket'

class GateTest < Minitest::Test
  def test_gate
    require 'byebug'; byebug
    umeda = Gate.new(:umeda)
    juso = Gate.new(:juso)
    ticket = Ticket.new(150)
    umeda.enter(ticket)
    assert juso.exit(ticket)
  end

  def test_umeda_to_mikuni
    umeda = Gate.new(:umeda)
    mikuni = Gate.new(:mikuni)

    ticket = Ticket.new(150)
    umeda.enter(ticket)
    refute mikuni.exit(ticket)
  end
end
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • y_waiwai

    2019/02/20 18:17

    プロを目指すなら、丸投げでぶん投げる質問はいかがなものかと思いますがw

    キャンセル

回答 2

checkベストアンサー

+5

「プロを目指す人のためのRuby入門」の著者の伊藤です。
拙著を読んでいただき、どうもありがとうございます。

enterメソッドで駅名が一緒に保存される理由がわかりません。。。

わからないポイントがいったいどこなのか、理解されているのはどこまでなのか、ちょっとこの質問文だけでは推測しかねるのですが、コードの動きを丁寧に説明してみますね。

以下のサンプルコードに、連番付きのコメントを付けてみました。
これを順番に追っていくと、切符に改札機の駅名が保存される理由がわかるかもしれません。

class GateTest < Minitest::Test
  def test_gate
    # 1. 私は改札機です。umedaという名前(@name)を持っています
    umeda = Gate.new(:umeda)
    juso = Gate.new(:juso)
    # 2. 私は切符です。150円という運賃(@fare)を持っています
    ticket = Ticket.new(150)
    # 3. umedaの改札機に、切符を挿入(enter)します
    umeda.enter(ticket)
    assert juso.exit(ticket)
  end

  # 省略
end

class Gate
  STATIONS = [:umeda, :juso, :mikuni]
  FARES = [150, 190]

  def initialize(name)
    @name = name
  end

  def enter(ticket)
    # 4. 受け取った切符(ticket)に対して、改札機の名前(@name)を記録(stamp)せよ、と伝えます
    ticket.stamp(@name)
  end

  def exit(ticket)
    fare = calc_fare(ticket)
    fare <= ticket.fare
  end

  def calc_fare(ticket)
    from = STATIONS.index(ticket.stamp_at)
    to = STATIONS.index(@name)
    distance = to - from
    FARES[distance - 1]
  end
end

class Ticket
  attr_reader :fare, :stamp_at

  def initialize(fare)
    @fare = fare
  end

  def stamp(name)
    # 5. 受け取った名前(name)を、通った駅名(@stamp_at)に保存します
    @stamp_at = name
  end
end

オブジェクト指向プログラミングは、上のように擬人法で考えると理解しやすいかもしれません。

上の説明でもまだピンとこない、擬人法で説明されてもイメージがわかない、という場合は、いったん本書を置いて、「ゼロからわかる Ruby超入門」のような、もう一段やさしめの本を読んでみることをお勧めします。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/02/21 14:06

    丁寧に解説していただきありがとうございます。
    説明不足申し訳ありません。

    4. 受け取った切符(ticket)に対して、改札機の名前(@name)を記録(stamp)せよ、と伝えます
    >> enterメソッドでticketを引数にしているのはticketと@nameを関連づけるためという認識で合っていますか?

    キャンセル

  • 2019/02/21 17:15

    > enterメソッドでticketを引数にしているのはticketと@nameを関連づけるためという認識で合っていますか?

    その認識でよいと思います。

    otnさんも回答されているとおり、現実の切符と改札機を考えたときに、

    - 切符を改札機に入れる
    - (おそらく)切符に通った改札機の駅情報が記録される

    という仕組みになっていると思うので、プログラム上でも `gate.enter(ticket)` のように、まずticketをgateにenterして(切符を改札機に入れて)、gate.nameをticketにstampする(駅名を切符に記録する)というふうに設計してみました。

    ただし、これはあくまで筆者が考えたコード設計ですので、他の人に同じ課題を出すと別の設計や実装が出てくる可能性があります。(というか、おそらくそうなると思います)

    キャンセル

  • 2019/02/21 20:55

    ありがとうございます。
    擬人法で考えてみるとよく分かりました。
    また、attr_reader :fare, :stamp_at の中身を考えることで
    コードの意味を理解できました。
    引き続き読み、頑張ります。

    キャンセル

0

その駅から入場したと言うことを記録するメソッドのようなので、駅名を保存するのでは?
切符を買って、自動改札を通れば、切符に駅を示すコードや日時が記録されますよ。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/02/21 15:46

    回答ありがとうございます。

    キャンセル

  • 2019/02/21 15:53

    あら、「理由(何故そうするか)」が分からないのじゃなくて、「仕組み(どういう手段でそうしているか)」が分からないという質問でした?

    キャンセル

  • 2019/02/21 20:57

    ありがとうございます。
    擬人法で考えてみることで仕組みを理解できました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.07%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る