この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
Ruby技術者認定試験(Gold)合格経験
■ 【使用教材】
Ruby リファレンスマニュアル(オンラインのドキュメント)
Ruby公式資格教科書 Ruby技術者認定試験Silver/Gold対応
メタプログラミングRuby
■ 【勉強方法】
Ruby公式資格教科書
教科書のとおりに、Gold範囲をしっかり読む。
ガイドの説明をしっかり読んだほうが効率的です。
3章、4章、5-9~5-12は重要です
2章 実行環境 2,3問ぐらい
* コマンドラインオプション
* 組み込み変数/定数
3章 文法 15問ぐらい
* 変数と定数
* 演算子
* ブロック
* 例外処理
* 大域脱出
4章 オブジェクト指向 (試験の肝の部分です)25問くらい。
* メソッドの詳細
* メソッドの可視性
* クラスの詳細
* クラスの継承
* モジュールの詳細
5-9~5-12 組み込みライブラリ 10問くらい。
* よく使用されるクラス(Object、Kernel、Module等)
* よく使用されるモジュール(Enumerable、Comparable等)
* 数値
* 正規表現
正規表現は基本的な使い方以外にも、 *? や +? などの最短マッチも出題されます。
6章 標準添付ライブラリ 2,3問ぐらい
* よく使用されるライブラリ(socket、rdoc等)
メタプログラミングRuby
オブジェクト指向について、教科書がない内容があります。
自分はヨドバシで立って読みました。
irbで試す(重要)
自分が試した注意点を共有します。
—————————————————————————-
クラスメソッドはクラスしか呼び出さない。
class C
def self.m
p “2”
end
end
C.new.m # undefined method `m’ for #<c:0x1fd7a80> (NoMethodError)
C.m # 2
—————————————————————————-
モジュールをクラスに extend すれば、モジュールのインスタンスメソッドがクラスメソッドになる
module Foo
def foo
p “foo”
end
end
class Hoge
extend Foo
end
Hoge.new.foo #undefined method `foo’ for #<hoge:0x1f07868> (NoMethodError)
Hoge.foo # foo
—————————————————————————-
initialize を定義しない場合は親クラスの initialize が自動で呼ばれます
class M1
def initialize
p “m1”
end
end
class M2 < M1
end
M2.new #m1
—————————————————————————-
super と super() は動作が異なります
super は現在のメソッドがオーバーライドしているメソッドを呼び出します。
括弧と引数が省略された場合には現在のメソッドの引数がそのまま引き 渡されます。
引数を渡さずにオーバーライドしたメソッドを呼び出すには super() と括弧を明示します。
例:
class Foo
def foo(arg=nil)
p arg
end
end
class Bar < Foo
def foo(arg)
super(5) # 5 を引数にして呼び出す
super(arg) # 5 を引数にして呼び出す
super # 5 を引数にして呼び出す super(arg) の略記法
arg = 1
super # 1 を引数にして呼び出す super(arg) の略記法
super() # 引数なしで呼び出す nil
end
end
Bar.new.foo 5
—————————————————————————-
インスタンス変数
class Sample
@value = “hello”
def value
@value
end
end
Sample.new.value #=> nil
Sample.class_eval { @value } #=> “hello”
クラス定義の中で初期化した、@valueは Sampleクラスオブジェクトのインスタンス変数で、
メソッド定義の中で、初期化した、@valueはSampleクラスオブジェクトのインスタンスのインスタンス変数になる。
インスタンス変数はクラス内で全メソッドで共通して使用することが出来ます。最初にどこかのメソッドで使用された時点でインスタンス変数は作成され、一度作成されたインスタンス変数は他のメソッドで値を取り出したり格納したりすることが出来るようになります。
class Foo
@v1=1
def self.read; @v1;end
def write; @v1=2;end
def read; @v1;end
end
=> nil
irb(main):017:0> obj=Foo.new
=> #<foo:0x000000174ce908>
irb(main):018:0> obj.write
=> 2
irb(main):019:0> obj.read
=> 2
irb(main):020:0> Foo.read
=> 1
—————————————————————————-
クラスとsuperクラス
irb(main):032:0* foo=Foo.new
=> #<foo:0x0000001d9caf78>
irb(main):033:0> foo.class
=> Foo
irb(main):034:0> foo.superclass
NoMethodError: undefined method `superclass’ for #<foo:0x0000001d9caf78>
from (irb):34
from /home/search/ruby/bin/irb:12:in `<main>’
irb(main):035:0> Foo.class
=> Class
irb(main):036:0> Foo.superclass
=> Object
irb(main):037:0> Class.class
=> Class
irb(main):038:0> Class.superclass
=> Module
irb(main):007:0> Module.superclass
=> Object
—————————————————————————-
クラス変数。トップレベル:object 全てのクラスの親クラス。
クラス変数は、親と子共有で使う
irb(main):001:0> @@v1=1
=> 1
irb(main):002:0> class Foo
irb(main):003:1> @@v1=2
irb(main):004:1> end
=> 2
irb(main):005:0> p @@v1
2
=> 2
—————————————————————————-
Object extend
irb(main):001:0> module M
irb(main):002:1> def m;”aa”;end
irb(main):003:1> end
=> nil
irb(main):004:0> obj=Object.new
=> #<object:0x00000011384670>
irb(main):005:0> obj.extend M
=> #<object:0x00000011384670>
irb(main):006:0> obj.m
=> “aa”
irb(main):007:0> class C
irb(main):008:1> extend M
irb(main):009:1> end
=> C
irb(main):010:0> C.m
=> “aa”
irb(main):011:0> c.new.m
NameError: undefined local variable or method `c’ for main:Object
from (irb):11
from /home/search/ruby/bin/irb:12:in `<main>’
—————————————————————————-
以下の2つのコード、include の位置を変えると表示される結果が異なります。
コード1
module M
@@x = 100
end
class A
@@x = 500
include M
end
module M
puts @@x # 100 と表示される
end
class A
puts @@x # 100 と表示される
end
コード2
module M
@@x = 100
end
class A
include M
@@x = 500
end
module M
puts @@x # 500 と表示される
end
class A
puts @@x # 500 と表示される
end
—————————————————————————-
モジュールで定義されたクラス変数(モジュール変数)は、そのモジュールをインクルードしたクラス間でも共有されます。
module Foo
@@foo = 1
end
class Bar
include Foo
p @@foo += 1 # => 2
end
class Baz
include Foo
p @@foo += 1 # => 3
end
—————————————————————————-
親クラスに、子クラスで既に定義されている同名のクラス変数を追加した場合には、 子クラスのクラス変数は子クラスで保存されます。
上書きされません。
class Foo
end
class Bar < Foo
@@v = :bar
end
class Foo
@@v = :foo
end
class Bar
p @@v #=> :bar
end
class Foo
p @@v #=> :foo
end
—————————————————————————-
トップレベルで定義すれば、Object中に定義され、親なので、子供も共有。下記は同じになる。
@@v=1
class Foo
end
class Bar < Foo
@@v = :bar
end
class Foo
@@v = :foo
end
class Bar
p @@v #=> :foo
end
class Foo
p @@v #=> :foo
end
p @@v #=> :foo
irb(main):002:0> @@v=1
=> 1
irb(main):003:0> class Foo
irb(main):004:1> @@v=2
irb(main):005:1> end
=> 2
irb(main):006:0> @@v
=> 2
irb(main):001:0> class Foo
irb(main):002:1> @@v=1
irb(main):003:1> end
=> 1
irb(main):004:0> p @@v
NameError: uninitialized class variable @@v in Object
from (irb):4
from /usr/bin/irb:12:in `<main>’
—————————————————————————-
irb(main):007:0> Module.class
=> Class
irb(main):008:0> Class.class
=> Class
irb(main):009:0> Class.superclass
=> Module
irb(main):005:0> Class.ancestors
=> [Class, Module, Object, Kernel]
irb(main):010:0> Module.superclass
=> Object
irb(main):001:0> module Foo
irb(main):002:1> @@foo = 1
irb(main):003:1> end
=> 1
irb(main):004:0> Foo.class
=> Module
irb(main):006:0> Foo.ancestors
=> [Foo]
irb(main):001:0> class Foo
irb(main):002:1> end
=> nil
irb(main):003:0> Foo.class
=> Class
irb(main):004:0> Foo.ancestors
=> [Foo, Object, Kernel]
—————————————————————————-
可変引数
可変長引数のデフォルト値は指定できません。
引数は配列として扱われる。
可変長引数は一つのメソッドは一つしか指定できません。
def foo(*args)
p args
end
def bar(*args)
foo(args)
end
def hoge(*args)
foo(*args)
end
実行結果は以下のとおり
bar(1, 2, 3, 4, 5) #=> [[1, 2, 3, 4, 5]]
hoge(1, 2, 3, 4, 5) #=> [1, 2, 3, 4, 5]
foo, bar = [1, 2] # foo = 1; bar = 2
foo, bar = 1, 2 # foo = 1; bar = 2
foo, bar = 1 # foo = 1; bar = nil
foo, bar, baz = 1, 2 # foo = 1; bar = 2; baz = nil
foo, bar = 1, 2, 3 # foo = 1; bar = 2
foo = 1, 2, 3 # foo = [1, 2, 3]
*foo = 1, 2, 3 # foo = [1, 2, 3]
foo,*bar = 1, 2, 3 # foo = 1; bar = [2, 3]
—————————————————————————-
合格者の合格経験を見る
http://rochefort.hatenablog.com/category/gold
■ 【感想】
Silverよりかなり難しいですが、試験内容は上記です。
ですので、重要な部分を理解して、irbで注意点などしっかり把握すれば、合格できます。