解決済み

Rubyの問題について質問です。

  • 困ってます
  • 質問No.8471410
  • 閲覧数208
  • ありがとう数11
  • 気になる数0
  • 回答数4
  • コメント数0

お礼率 100% (4/4)

Rubyの資格試験の勉強をしています。
分からない部分がありまして質問させていただきます。
class Employee
attr_reader :id
attr_accessor :name
def initialize id , name
@id = id
@name = name
end
def to_s
return "#{@id}:#{@name}"
end
def <=> other
return self.id <=> other.id
end
employees = [ ]
employees <<Employee.new("3","Tanaka")
employees<<Employee.new("1","Suzuki")
employees<<Employee.new("2","Sato")
employee.sort!

(質問)
「return self.id <=> other.id」この部分のselfとotherが何をさしているのか分かりません。3つめでインスタント化している「employees<<Employee.new("2","Sato")」のは、selfに入りそれまでに入れた値はotherに入っているのでしょうか?

ご回答よろしくお願いします。

質問者が選んだベストアンサー

  • 回答No.3

ベストアンサー率 77% (490/633)

まず最初に間違いがありますので、それを修正しないと動きません。
employees = [ ]の上の行に
end
を追加する必要があります。そのままではエラーがでます。

また、最後の行は
employee.sort!
ではなく
employees.sort!
です。変数名が間違っていますので、これもエラーがでます。

デバッガを使えば質問の内容は簡単に確認できますので、それを使うのが理解する早道です。

それはそれとして、
>「return self.id <=> other.id」この部分のselfとotherが何をさしているのか分かりません。

def <=> otherがどのような形で呼ばれるかを考えればわかります。
このメソッドはsort!から呼ばれます。
return self.id <=> other.id
の行で最初に実行を止めたときのデバッガの出力を書いておきます。
(byebug) self
#<Employee:0x007fe12416ccb0 @id="3", @name="Tanaka">
(byebug) other
#<Employee:0x007fe12416c9b8 @id="1", @name="Suzuki">
この場合はsort!からは、はじめに、employees[0]<=>employees[1]の形で呼ばれています。
ここでは、def <=> otherが定義されていますので、
self.id <=> other.id
で比較されます。つまり "3" <=> "1"が実行されます。

>3つめでインスタント化している「employees<<Employee.new("2","Sato")」のは、selfに入りそれまでに入れた値はotherに入っているのでしょうか?

selfとotherのどちらになるかはsort!次第です。

余談ですが、
idが文字列になっていますので、文字列で比較されます。数値で比較したいのでしたら、
employees <<Employee.new(3,"Tanaka")
のようにidを数値にする必要があります。あるいは
return self.id.to_i <=> other.id.to_i
のように。
お礼コメント
tanakayasufumi

お礼率 100% (4/4)

とても分かりやすい説明ありがとうございました。
投稿日時 - 2014-02-12 07:49:03

その他の回答 (全3件)

  • 回答No.4

ベストアンサー率 64% (135/210)

> 「return self.id <=> other.id」この部分のselfとotherが何をさしているのか分かりません。


下のプログラム3行目のtanakaがself, suzukiがotherです。
-----
tanaka = Employee.new(3,"Tanaka")
suzuki = Employee.new(1,"Suzuki")

p tanaka <=> suzuki # 結果は、1
p tanaka.<=>(suzuki) # これも同じこと
-----


employees << Employee.new("2","Sato")

employeesという配列(Array)にEmployee.new("2","Sato")という要素を追加しています。
employees.sort!で各要素間でself<=>otherの比較が行われて、その結果により順番の入れ替えを行って要素をid順にソートしています。

-----
employees.sort!
employees.each do |emp|
p emp
end
-----
-----結果(id順にソートされている---
#<Employee:0x1082acc @id=1, @name="Suzuki">
#<Employee:0x1082a90 @id=2, @name="Sato">
#<Employee:0x1082af4 @id=3, @name="Tanaka">
-----
お礼コメント
tanakayasufumi

お礼率 100% (4/4)

それぞれの動きが分かりやすかったです。ありがとうございます。
投稿日時 - 2014-02-12 07:52:09
  • 回答No.2

ベストアンサー率 48% (325/664)

んーと、これ最後の end は 2 つじゃないですか?
そうしないと Employee クラスの定義が終わりませんが……。

それはともかく、
def <=> other
return self.id <=> other.id
end
の self と other が何かという質問ですが、この部分は Employee クラスに対する <=> 演算子(別名 宇宙船演算子)の定義をしています。
http://www.minituku.net/courses/566428009/lessons/938940278/texts/873491413?locale=en
定義の内容は self の id メソッドの結果と other の id メソッドの結果に対して <=> を使った結果をそのまま Employee クラスに対する <=> 演算子の結果とする、というものになっています。

other については def の部分をこう書きかえて、<=> 演算子もメソッドの一種であることがわかればわかると思います。
def <=>(other)

では self は何かというと、これはクラスインスタンスメソッドの中で使うとそのメソッドが呼ばれているインスタンス自体を表します。

したがって、
> 3つめでインスタント化している「employees<<Employee.new("2","Sato")」のは、selfに入りそれまでに入れた値はotherに入っているのでしょうか?
は全く見当はずれな内容となっています。
お礼コメント
tanakayasufumi

お礼率 100% (4/4)

ミニツクのリンクありがとうございます。<=>宇宙船演算子というんですね。初めて知りました。
投稿日時 - 2014-02-12 07:51:03
  • 回答No.1

ベストアンサー率 48% (4413/9095)

違います。

<=> は明示的には呼び出されてませんが、sort! から呼び出されます。
sortについて調べてみてください。
お礼コメント
tanakayasufumi

お礼率 100% (4/4)

まさかsort!とセットになってるとは気づきませんでした。ありがとうございます。
投稿日時 - 2014-02-12 07:53:04
結果を報告する
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。
関連するQ&A
AIエージェント「あい」

こんにちは。AIエージェントの「あい」です。
あなたの悩みに、OKWAVE 3,600万件のQ&Aを分析して最適な回答をご提案します。

その他の関連するQ&A、テーマをキーワードで探す

キーワードでQ&A、テーマを検索する

ピックアップ

ページ先頭へ