圧倒的備忘録

忘却は罪である。

【Ruby入門】インスタンスからクラスの変数を取得・変更する方法

Rubyは以下の図のようにインスタンスからクラスにアクセスできない仕様になってます。 f:id:istn:20180824170755p:plain

# -*- coding: utf-8 -*-
require 'date'
# Musicクラスをつくる
    class Music
        # Musicクラスのインスタンスを初期化する
        def initialize(title)
            @title = title
        end
    end
# Musicクラスのインスタンスを作成する
music = Music.new "戦場のメリー・クリスマス"
puts "曲名:" + music.title

一件、このコードは問題ないように見えますが、@titleは「クラスインスタンス変数」と呼ばれる変数として扱われるため、下記のエラーが生じアクセスすることができないのです。 実行結果:

 undefined method `title' for #<Music:0x0000000003f91c28> (NoMethodError)

では、インスタンスからクラスの変数を取得・変更するにはどのようにすればよいでしょうか?

f:id:istn:20180824172449p:plain それには、ゲッターを使います。

ゲッター

オブジェクトの属性を取得する操作です。以下のように、ゲッターを使うとインスタンスから変数@titleを取得することが可能となります。

# -*- coding: utf-8 -*-
# Musicクラスをつくる
    class Music
        # Musicクラスのインスタンスを初期化する
        def initialize(title)
            @title = title
        end
        # title属性のゲッターメソッド
        def title
            @title
        end
    end
# Musicクラスのインスタンスを作成する
music = Music.new "戦場のメリー・クリスマス"
puts "曲名:" + music.title

実行結果:

曲名:戦場のメリー・クリスマス

ゲッターにより、インスタンスから変数を取得することができるようになりました。では、インスタンスの値を変更するにはどのようにしたらよいでしょうか?セッターを使います。

# -*- coding: utf-8 -*-
# Musicクラスをつくる
    class Music
        # Musicクラスのインスタンスを初期化する
        def initialize(title)
            @title = title
        end
        # title属性のゲッターメソッド
        def title
            @title
        end
  # title属性のセッターメソッド
        def title=(value)
            @title = value
        end
    end
# Musicクラスのインスタンスを作成する
music = Music.new "戦場のメリー・クリスマス"
# セッターを使ってtitileの値を変更する
music.title = "ライディーン"
puts "曲名:" + music.title

ゲッターとセッターを使うことにより、オブジェクトの値を取得・設定することが可能となりました。しかし、多数のインスタンス変数の全てについて、ゲッター・セッターメソッドを用いるのはかなり煩雑です。そこで、アクセサを使います。

アクセサとは

オブジェクトの属性を取得、設定する操作のことです。ゲッターとセッターを併せ持った操作です。

# -*- coding: utf-8 -*-
# Musicクラスをつくる
    class Music
        # Musicクラスのインスタンスを初期化する
        def initialize(title,composer)
            @title = title
            @composer = composer
        end
        # title属性、age属性のアクセサ
        attr_accessor :title, :composer
        # Musicクラスのインスタンスの文字列表現を返す
        def to_s
            "#@title, #@composer"
        end
    end
# Musicクラスのインスタンスを作成する
music = Music.new '戦場のメリークリスマス', '坂本龍一'
# アクセサを使ってtitileの値を変更する
music.title = "ライディーン"
puts "曲名:" + music.title + "\n作曲者:" + music.composer

これにより、ゲッターとセッターを一つ一つ定義することなく、オブジェクトの値を取得・更新することが可能です。とても、便利な操作ですので、この際に抑えておきましょう!

【Ruby入門】classのnewとinitializeについて

classとは

変数などのデータとそれを処理するメソッドをまとめたものを指します。

Rubyでclassを使うためには、以下のようにコード中でclassを定義する必要があります。

class クラス名
    # クラスのデータを初期化する
    def initialize(引数)
      処理1
      処理2
      処理3
  ・・・
    end
end

defとは

メソッドを定義するものです。

initialize

クラスのデータを初期化するものです。複数のinitializeは定義できません。

クラスの定義をしましたが、そのままではclassをコード中で使えません。 classのnewメソッドによって、classをインスタンス化する必要があります。

インスタンス化とは

classの定義をもとに新たな変数を作成することです。

# Studentクラスを定義する
class Student
    # Studentクラスのname,ageデータを初期化する
    def initialize(name,age)
        @name = name
        @age = age
    end
    def introduce
       puts "私は#{@name}です。#{@age}歳です。"
    end
end
# Studentクラスのインスタンスを作成し、変数化する。
yamada = Student.new('やまだたろう',21)
tanaka = Student.new('たなかゆうき',18)

# yamada,tanakaインスタンスを出力する。
print yamada.introduce
print tanaka.introduce

実行結果:

 私はやまだたろうです。21歳です。
 私はたなかゆうきです。18歳です。

Student.newメソッドを使って、Studentクラスをインスタンス化してます。その後、変数yamada,tanakaに対してintroduceメソッドを実行するように命令してます。その結果、Studentクラスのintroduceメソッドが実行されます。このように、classは定義したままでは使用できず、newメソッドによりインスタンス化して初めて、classのメソッドが使用できるようになります。例えるならば、クラスがたい焼き機械の型 インスタンスがたい焼きそのものというイメージです。

【Ruby入門】「to_s」、「to_i」について

Rubyでは文字列と数値は別のオブジェクトのため、連結ができません。 そのため、次のようなケースだとエラーが起きます。

puts "I am " + 27 + "years old."
# :in `+': no implicit conversion of Integer into String (TypeError)

そこで、to_sメソッドの登場です。

to_sメソッドとは

値を文字列に直して返すメソッドです。このメソッドを使うことにより、 データ型が一致してエラーが直ります。

puts "I am " + 27.to_s + " years old."
=> I am 27 years old  

一方、値を数値に直して返すメソッドは「to_i」メソッドを使います。 初心者がつまづきやすいポイントですので、この際に抑えておきましょう!

【Ruby入門】変数展開のメリットについて

変数展開のメリットについて

変数展開は文字列の連結と役割としては同じですが、1つ異なる点があります。 それは下のコードのように、文字列と数値を連携することができないことです。

age = 30
puts age + "歳になりました。"

# エラーになります。

しかし、次のように変数展開を用いると、数値の入った変数も問題なく文字列に含めることが可能です。

age = 30
age + "歳になりました。"

puts "#{age} + 歳になりました。"

# 「30歳になりました」と表示されます。

型としては、"#{変数名}"として使います。変数を文字列に含める場合は、基本的に変数展開を使うようにしましょう。

【Ruby入門】getsメソッドのデータ型エラーを解消するには

要件

-ユーザーが入力した値の1%分のポイントを表示する。 -ユーザーが入力した値が1000円以上の場合には、1%分のポイント+50ポイントを表示する。

【失敗例】

money = gets
point = money / 100

if money >= 1000
    puts point + 50
else
    puts point
end

次のような、エラーが表示されて処理が実行されません。 test02.rb:2:in <main>': undefined method/' for "1200\n":String (NoMethodError)

これは、getsメソッドに原因があります。getsメソッドはキーボードで入力した値を取得しますが、文字列として取得します。そのため、文字列を数値として計算しようとしたため、怒られてしまうのです。そのため、ここでは数値として値を取得してくれる.to_iメソッドを使いましょう!

money = gets.to_i
point = money / 100
if money >= 1000
    puts point + 50
else
    puts point
end

これにより、エラーが改善することが可能です!

【Ruby入門】getsとgets.chompの違い

getsとgets.chompのち外

gets

キーボードで入力した文字列を取得します。

gets.chompメソッド

キーボードで入力した文字列の改行コードを削除して取得します。

つまり、getsは改行が生じ、gets.chompは改行が生じません。 実際の例をみてみましょう!

# -*- coding: utf-8 -*-
name = gets
puts "こんにちは" + name + "さん"

getsメソッドを使った場合は、 " こんにちは○○ さん" と改行が生じます。それに比べgetsメソッドを使った場合は、

# -*- coding: utf-8 -*-
name = gets.chomp
puts "こんにちは" + name + "さん"
'''
"こんにちは○○さん"と改行が表示されずに表示されます。