こんにちは。アルバイトの大木です。普段プログラミングをしていて何気なく使っている変数ですが、スコープを意識して使っていますか?スコープと言うとかっこよく聞こえますが、要するに、変数にアクセスできる範囲のことです。この範囲は変数の種類によって異なります。
Rubyの4種類の変数定義方法
ルーターはクローリング会社として、nokogiriやselenium/mechanizeの使いやすさからRubyを共通言語として採用しています。
例えば、Rubyだと主に以下の4種類の変数があります。
ローカル変数
rooter = "ルーター"
変数と聞くと思い浮かべるのはこのローカル変数ではないでしょうか?スコープは、変数が宣言されたブロック、メソッドやクラス定義の終わりまでです。
class Company
rooter = "ルーター"
def syoukai
puts rooter + "です"
end
end
company = Company.new
company.syoukai #undefined local variable or method `rooter'
このように、ローカル変数はメソッドをまたいでアクセスすることはできません。
インスタンス変数
@rooter = "ルーター"
このように、@をつけることで表現できます。スコープは同じインスタンスの範囲内です。なので、インスタンスごとに値を持ちます。
class Company
def initialize(rooter)
@rooter = rooter
end
def syoukai
puts @rooter + "です"
end
end
company_name = Company.new("ルーター")
company_work = Company.new("スクレイピング")
company_name.syoukai #ルーターです
company_work.syoukai #スクレイピングです
このように、クラス内のインスタンスメソッドからアクセスすることができました。
クラス変数
@@rooter = "ルーター"
このように@@をつけることで表現できます。スコープはそのクラスの全てのインスタンスです。しかし、クラス変数はクラス内に一意に値を持つ変数です。
class Company
def initialize(rooter)
@@rooter = rooter
end
def syoukai
puts @@rooter + "です"
end
end
company_name = Company.new("ルーター")
company_work = Company.new("スクレイピング")
company_name.syoukai #スクレイピングです
company_work.syoukai #スクレイピングです
つまり、インスタンス変数とは違って、変数の値が上書きされてしまいます。
インスタンス変数とクラス変数は似ていますが、インスタンスごとに違った値を与えたいときはインスタンス変数を使うなど使い分けていく必要がありそうです。
クラスインスタンス変数
4つ目はクラスインスタンス変数という一番凄そうな変数です。その名の通り、クラス変数にもインスタンス変数にも似た特徴を持っています。見た目はインスタンス変数と同じように@をつけて表現しますが、クラス変数と似たような働きをします。しかし、そのクラスでしかアクセスできません。
class Company
@rooter = "ルーター"
def syoukai
puts @rooter
end
def self.intro
puts @rooter
end
end
class Office < Company
end
Company.intro #ルーター
company = Company.new
company.syoukai #nil
Office.intro #nil
1つ目の出力結果のようにクラスメソッドからクラスインスタンス変数はアクセスできるが、2つ目はクラスインスタンス変数がインスタンス変数と見なされ、インスタンスメソッドからクラスインスタンス変数はアクセスできません。3つ目が特徴で、継承されたクラスからクラスインスタンス変数はアクセスできないことを示しています。
まとめ
自分はローカル変数とインスタンス変数しか意識していなかったのですが、調べてみるといろいろな変数がありました。普段からスコープを意識して変数を使っていきたいですね。