クモのようにコツコツと

フロントエンドエンジニア イイダリョウの技術ブログ。略称「クモコツ」

【Ruby】クラスとオブジェクトを作成(class)

Rubyの続きです。前回はメソッドの定義と実行を行いました。今回はクラスとオブジェクトを作ります。クラスの継承というオブジェクト指向らしい内容にだんだん入ってきました。それではいきましょう!

【目次】

Ruby/Ruby on Railsを習得するためにやったこと まとめ
qiita.com

クラスの作成(class)

今回も「20分ではじめるRuby」を参考に進める。今回のテーマはクラス。下記のページの「挨拶人(Greeter)への進化」のところから。

※参考:20分ではじめるRuby

まずクラスの作成

# クラス
class Greeter
    def initialize(name = "世界")
        @name = name
    end

    def say_hi
        puts "こんにちは、#{@name}!"
    end

    def say_bye
        puts "さようなら、#{@name}!"
    end
end

頭にclassを付けて、クラス名は一文字目を大文字にする

※参考:クラス/メソッドの定義 (Ruby 3.3 リファレンスマニュアル)

クラス(英:class)とはオブジェクト指向で出てくる概念のひとつであり「それが、どんなものか」を表した設計図のことです。

※参考:クラスとは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典


クラスの中でメソッドをいくつか実行している。一つ目のinitializeの引数nameには初期値「世界」を設定している。

メソッドや初期値については前回の記事参照。

※参考:【Ruby】メソッドの定義、実行(def〜end) - クモのようにコツコツと


@nameのところは「インスタンス変数」というようだ。

`@'で始まる変数はインスタンス変数であり、特定のオブジェクトに所属しています。インスタンス変数はそのクラスまたはサブクラスのメソッドから参照できます。

※参考:変数と定数 (Ruby 3.3 リファレンスマニュアル)


クラスsay_hisay_byeの中に「式展開」#{ }@nameを埋め込んで表示している。

式展開についても前回の記事を参照。

※参考:【Ruby】メソッドの定義、実行(def〜end) - クモのようにコツコツと

オブジェクトの作成(new)

次にオブジェクトを作成する。

※参考:20分ではじめるRuby

# オブジェクト
greeter = Greeter.new("ジョン")
greeter.say_hi
greeter.say_bye
  • greeterオブジェクトでGreeterクラスをnewで継承し、引数に「ジョン」を入れる。
  • greeterオブジェクトでsay_hiメソッドを実行
  • greeterオブジェクトでsay_byeメソッドを実行

newによって自身のインスタンスを生成して返す。

※参考:Class#new (Ruby 3.3 リファレンスマニュアル)

インスタンス(英:instance)とはオブジェクト指向で出てくる概念のひとつであり設計図(クラス)を具現化した「実体」のことです。

※参考:インスタンスとは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典


Rubyを起動した実行結果

% ruby ri20min_7.rb
こんにちは、ジョン!
さようなら、ジョン!
  • say_hiメソッドに引数「ジョン」が入ったテキストが表示される
  • say_byeメソッドに引数「ジョン」が入ったテキストが表示される

なお、greeterオブジェクトでインスタンス変数@nameを呼び出すことはできないようだ。

# 名前は直接取得できない(エラーになる)
greeter.@name

結果はエラーになった

% ruby ri20min_7.rb
ri20min_7.rb: --> ri20min_7.rb
expected a method name
> 24  greeter.@name
ri20min_7.rb:24: syntax error, unexpected instance variable (SyntaxError)
greeter.@name
        ^~~~~

ソースコード

※参考:get-started-with-ruby-in-20-minutes/ri20min_7.rb at main · ryo-i/get-started-with-ruby-in-20-minutes · GitHub

メソッドを呼び出す(instance_methods)

他にもいろいろ呼び出して表示してみる。

まずinstance_methodsGreeterクラスのメソッドを呼び出してみる。

puts "すべてのメソッド:"
puts Greeter.instance_methods

instance_methodsライブラリについて

そのモジュールで定義されている public および protected メソッド名の一覧を配列で返します。

※参考:Module#instance_methods (Ruby 3.3 リファレンスマニュアル)


Rubyを起動した実行結果

すべてのメソッド:
say_hi
say_bye
singleton_class
dup
itself
methods
singleton_methods
protected_methods
private_methods
public_methods
instance_variables
instance_variable_get
instance_variable_set
instance_variable_defined?
remove_instance_variable
instance_of?
kind_of?
is_a?
display
public_send
extend
clone
frozen?
class
<=>
tap
yield_self
then
===
!~
method
nil?
public_method
singleton_method
eql?
respond_to?
define_singleton_method
hash
freeze
inspect
object_id
send
to_s
to_enum
enum_for
equal?
!
__send__
==
!=
instance_eval
instance_exec
__id__

Greeterクラスの親や祖先のクラスで定義されたすべてのメソッドが表示されるようだ。


instance_methodsメソッドの引数にfalseを入れるとGreeterクラスの中のメソッドのみが表示されるようだ。

puts "Greeterのメソッド:"
puts Greeter.instance_methods(false)

Rubyの実行結果

Greeterのメソッド:
say_hi
say_bye

Greeterクラスの中のsay_hisay_byeメソッドのみが表示されている。

メソッドの真偽を調べる(respond_to)

次にgreeterオブジェクトのメソッドの真偽を調べる。

# オブジェクト
greeter = Greeter.new("ジョン")

puts "name:"
puts greeter.respond_to?("name") #falseになる
puts "say_hi:"
puts greeter.respond_to?("say_hi")
puts "say_bye:"
puts greeter.respond_to?("say_bye")
puts "to_s:"
puts greeter.respond_to?("to_s")

namesay_hisay_byeto_sの存在をrespond_toライブラリで調べる。

respond_toライブラリについて

オブジェクトがメソッド name を持つとき真を返します。

※参考:Object#respond_to? (Ruby 3.3 リファレンスマニュアル)

to_sは先ほどの親&先祖のメソッド一覧の中に含まれていたメソッド。

何かを文字列に変換するもので、 すべてのオブジェクトに標準で定義されているメソッドです

※参考:20分ではじめるRuby
※参考:String#to_s (Ruby 3.3 リファレンスマニュアル)


Rubyの実行結果

name:
false
say_hi:
true
say_bye:
true
to_s:
true

一つ目のnameのみがfalseになり、アクセスできないことがわかる。


ソースコード

※参考:get-started-with-ruby-in-20-minutes/ri20min_8.rb at main · ryo-i/get-started-with-ruby-in-20-minutes · GitHub

nameとname=を定義する(attr_accessor)

Greeterクラスの冒頭でattr_accessorを使ってnamename=を定義する

# クラス
class Greeter
    attr_accessor :name

    # 中略(変更なし)
end

その下のinitializesay_hisay_byeメソッドは変更なし

attr_accessorを使うと2つの新しいメソッドが定義されます。 nameは値を参照するメソッドで、name=は値を設定するメソッドです。

※参考:Module#attr_accessor (Ruby 3.3 リファレンスマニュアル)

インスタンス変数 name に対する読み取りメソッドと書き込みメソッドの両方を定義します。


namename=を呼び出してみる

# オブジェクト
greeter = Greeter.new("ジョン")

puts "name:"
puts greeter.respond_to?("name") #trueになる
puts "name=:"
puts greeter.respond_to?("name=") #trueになる

rubyの実行結果

% ruby ri20min_9.rb
name:
true
name=:
true

今度はどちらもtrueになった!

名前を変更する(name=)

name=で名前を変更してみる

greeter.say_hi

greeter.name="ジョージ"
puts "名前を変更"
puts greeter.name
greeter.say_hi

greeter.name="ポール"
greeter.say_hi

greeter.name="リンゴ"
greeter.say_bye

rubyの実行結果

こんにちは、ジョン!
名前を変更
ジョージ
こんにちは、ジョージ!
こんにちは、ポール!
さようなら、リンゴ!

名前が変更できた!


ソースコード

※参考:get-started-with-ruby-in-20-minutes/ri20min_9.rb at main · ryo-i/get-started-with-ruby-in-20-minutes · GitHub

最後に

とうことで今回はクラスとオブジェクトを作成しました。引数の名前も変更できました。クラスの継承でだんだんオブジェクト指向っぽい世界に入ってきた感じがします♪

次回は「20分ではじめるRuby」編としては最終回。条件分岐、繰り返しなどもう少し凝った処理に入っていく予定です。それではまた!


Ruby/Ruby on Railsを習得するためにやったこと まとめ
qiita.com