Rubyに関してちょっとクイズです。
↓の記事が面白かったので、僕も少し書こうと思います。
https://qiita.com/aimof/items/cf89d83b2760c65abd84
スーーーーゴおおおおおい基本的なことだからみんなわかるよね。
トップレベルに関して
とりあえず、これを解いてみよう。
以下の記述がされたファイルを実行するとどんな実行結果が得られるだろう?
puts "1"
class User
puts "2"
def initialize(name)
@name = name
end
def name
@name
end
end
puts "3"
user = User.new("太郎")
puts user.name
1.太郎が出力される
2.1、2、3、太郎が出力される
3.2、太郎が出力される
4.3、太郎が出力される
解答
2.1,2,3,太郎が出力される
不正解だった方はドンマイなので、この記事を読み進めてもいいんじゃないでしょうか。
全て出力されます。
putsメソッドがなぜ使えるのかがポイントです。putsはKarnelモジュールで定義されていて、Objectクラスがそれをincludeしています。全てのクラスの元がObjectクラスとなるので、putsメソッドが使えるわけですね。
Userクラスの外は何かっていうことがポイントですが、とりあえず次の問いに行ってみましょう。
トップレベルの扱いに関して
これはどうでしょう。パッと見selfが何かわかりますかね。
puts self
class User
puts self
def initialize(name)
@name = name
end
def name
puts self
@name
end
end
puts self
user = User.new("太郎")
puts user.name
1.main、main、main、User、太郎
2.main、User、main、0x0000000004a5f3f8のようなもの、太郎
3.nil、User、User、User,太郎
4.エラーが起きて実行できない
解答
2.main、User、main、オブジェクトID、太郎
selfの問いです。クラス外はmain、Userクラス内はUser,Userクラスのnameメソッド内は0x0000000004a5f3f8のような文字列となります。
先ほどのputsが使えた理由は、mainがオブジェクトクラスのインスタンスだからですね。
トップレベルのメソッドの扱いに関して
最初ruby勉強するときなんかはファイルにメソッド書いて、呼び出してとかやると思うんだ。
でもさ、そもそもこれってなんで実行できるの?クラスも定義していないよ??
def print_hello
puts "hello"
end
print_hello
解答
トップレベルに書いたメソッドは、Objectクラスのprivateメソッドになります。
トップレベルで定義したら、Kernelモジュールのメソッドとして定義したのと同じ扱い。putsとかと同じように使えるってことだね。
アクセサメソッドに関して
簡単でしょう。
これはどんな出力がされるでしょう?
class User
attr_accessor :name
def initialize(name)
self.name = name
end
end
user = User.new("太郎")
puts user.name
1.何も出力されない
2.太郎が出力される
3.nilが出力される
解答
2.太郎が出力される
インスタンス変数を機械的に使っていると、あんまりみない書き方かもしれない。
これは太郎が出力されます。アクセサメソッドを使うときには、@name
なんかとするものを多く見るから新鮮かもしれない。
クラスの継承
次はこれで。
クラス変数って継承されるんですかね?
class Animal
@@name = "animal"
def name
puts @@name
end
end
class Dog < Animal
def name
puts @@name
end
end
dog = Dog.new
dog.name
1.「animal」が出力される
2.何も出力されない
3.エラーが起きて実行できない
解答
1.「animal」が出力される
クラス変数は継承したクラスでも使うことができます。
モジュールとクラスのメソッドってどっちが優先なの?
それじゃあ。次はこれだ。
割と簡単なはず。
class Animal
end
module Bow
def bow
puts "うおおおおおおおおん"
end
end
class Dog < Animal
include Bow
def bow
puts "わんわん"
end
end
dog = Dog.new
dog.bow
1.「うおおおおおおおおん」が出力される
2.「わんわん」が出力される
3.何も出力されない
解答
2
クラスに定義されているメソッドが先か取り込んだモジュールのメソッドが先かという問いです。同じメソッドがあった場合、クラス→モジュールの順で呼ばれます。
クラスからsuperでモジュールのメソッドを呼び出せるの?
最後です。モジュールは継承はできないよね。クラス内のメソッドの中、superを使ってモジュール内の同名称のメソッドを呼び出すことはできるのでしょうか?
module Bow
def bow
puts 'bowbow!!'
end
end
class Dog
include Bow
def bow
super
puts 'うおおおおおおおおおおおおおん!!'
end
end
dog = Dog.new
dog.bow
- 「うおおおおおおおおおおおおおん!!」が出力される
- 「bowbow!!」が出力される
- 「bowbow!!」「うおおおおおおおおおおおおおん!!」が出力される
解答
3. 「bowbow!!」「うおおおおおおおおおおおおおん!!」が出力される
クラスの中にメソッドを定義し、その中から同名称のモジュールのメソッドをsuperで呼び出すことはできます。
まとめ
ざっと書いてみましがたが、全て論理的に説明できるでしょうか。
rails使ってアプリケーションを作っていくのもいいけど、たまにはRubyの基本を見るのもいいかもしれないですね。