Edited at

ruby gold 落ちました・・・

More than 3 years have passed since last update.


はじめに

今年の4月からrailsでお仕事してます。

ruby silverを取得したのは今年の7月。

goldの勉強始めたのは2週間前くらい。

主に公式問題集を使って勉強してました。

Ruby公式資格教科書 Ruby技術者認定試験 Silver/Gold対応

追記(2015/9/13)

新しい公式問題集出てました。

Ruby技術者認定試験合格教本 Silver/Gold対応 Ruby公式資格教科書

先月出たみたいですね知らなかった。模擬問題も実際の試験に近い(?)気もしました。あと、確認問題が30問に増えてました。

公式の模擬問題では9割くらい取れてたんですが、実際の試験は

70/100

あと5点・・・悔しい・・・・

感想を述べると、公式の問題集についてる過去問よりも全然難しかったです・・・・。

あとは、2.1の改訂のお知らせもちゃんと見ておくべきだと思いました。

ちょこちょこ出ました。

Ruby技術者認定試験改訂のお知らせ

あとはメソッド探索。

これが1番重要かと。

結構な割合占めてた気がします。

ここをもっとしっかりやるべきでした・・・・。


復習

ちょっとうろ覚えだけど


Module#prepend

irb(main):001:0> module M

irb(main):002:1> def foo
irb(main):003:2> puts "M#foo"
irb(main):004:2> end
irb(main):005:1> end
=> :foo
irb(main):006:0> class C
irb(main):007:1> prepend M
irb(main):008:1> def foo
irb(main):009:2> puts "C#foo"
irb(main):010:2> end
irb(main):011:1> end
=> :foo
irb(main):012:0> C.new.foo
M#foo
=> nil


指定したモジュールを self の継承チェインの先頭に「追加する」ことで self の定数、メソッド、モジュール変数を「上書き」します。


引用:http://docs.ruby-lang.org/ja/2.0.0/method/Module/i/prepend.html

試験前にみてこれめっちゃ出そうだな、って思ったら案の定でました。

実際に問われたのはprependしたときのancestorsの結果でした。

irb(main):001:0> module M

irb(main):002:1> end
=> nil
irb(main):003:0> class A
irb(main):004:1> end
=> nil
irb(main):005:0> class B < A
irb(main):006:1> prepend M
irb(main):007:1> end
=> B
irb(main):008:0> B.ancestors
=> [M, B, A, Object, Kernel, BasicObject]

prependされたモジュールが一番最初にくるのですね、普通に間違えた。悲しい


Fiber

> f = Fiber.new {

* x = 0
> loop do
* Fiber.yield(x)
> x += 1
> end
> }
=> #<Fiber:0x802e2c84>
> 3.times do
* p f.resume
> end
0
1
2
=> 3

↑が2.1の改訂のお知らせに乗っていたやつです。

実際出たのはこんな感じ。

f = Fiber.new{

puts "hoge"
}

p "foo"
p f.resume
p "bar"


yaml


  • yamlを読み込む
    YAML.load(str)


  • yamlの書き出し
    YAML.dump(obj, io = nil)

詳しくはこちら

yamlっていろんな言語で使えるんだね・・・知らなかった


Threadクラス(組み込みクラス)

スレッド中の例外について問われました。


スレッドの中で例外が発生したとき、その例外をrescueで捕捉しなかった場合には、通常そのスレッドのみが警告なしに終了します。ただし、そのスレッドをjoinメソッドで待っているほかのスレッドがあった場合には、待っているスレッドに対し同じ例外が再度発生します。(公式問題集より)


プログラムを-dオプション付きで実行すると、プログラム自体が終了します。


-Iオプション

-Iオプションを指定すると

グローバル変数$LOAD_PATHにパスが追加されます。($LOAD_PATHにディレクトリを追加します。)

これは、公式問題集の模擬問題にもあった問題だけど、複数選択なので迷ってしまった・・。


例外処理


  • rescue句で、例外クラスを指定しなかった場合に捕捉されるのは・・・?


ここまでのrescue節は、例外クラスを指定せず使用しました。この場合、StandardErrorと、そのサブクラスが捕捉の対象となります。(公式問題集より)


普通に書いてあった・・・98ページに書いてあったよ・・・

ちゃんとマーカーで線引いてたのに間違えた・・・悔しい・・・


self

module M

$m = self
end

class A
$a = self
end

class B < A
include M
$b = self
end

c = B.new
$c = c.class

puts $m #=> M
puts $a #=> A
puts $b #=> B
puts $c #=> B

selfをちゃんと意識しないとダメですね・・・!

たぶんあってたと思う。


freeze(凍結状態)

リファレンスはこちら

これ読んでみると、この辺あんまり理解していなかったかも。感覚で解いてた。


標準クラスのオブジェクトでは、凍結したあとで破壊的なメソッド(レシーバ自身を変更するメソッド)を呼び出すと例外が発生します。


irb(main):026:0> s = "hello"

=> "hello"
irb(main):027:0> s.freeze
=> "hello"
irb(main):028:0> s.upcase! rescue $!
=> #<RuntimeError: can't modify frozen String>

RuntimeError発生してます。

でも、


ただし、インスタンス変数の参照先のオブジェクトは変更可能です。自作のクラスで参照先のオブジェクトまで変更不可にするには、freezeメソッドを再定義する必要があります。


class Cat

attr_accessor :name
def initialize(name)
@name = name
end
end

cat = Cat.new("Tama")
cat.freeze
(cat.name = "Piko") rescue p $! #=>#<RuntimeError: can't modify frozen Cat>

puts cat.name.replace("Piko") #=> Piko
puts cat.name #=> Piko

か、変わってるーーーー!

参照先のオブジェクトは変更できるんですね。

これも曖昧にしか覚えてない。


おわりに

公式問題集もっと読み込まないとだめですね・・・

読んだところも忘れたりしてるし。

あとは、模擬問題解いて正解してわかったつもりになってるのが多かったなぁ・・・。

ひねった問題出た時にわかってない。

次回に向けて頑張ります。

継承についてもちゃんと復習するけど長くなりそうなので別の投稿で・・・!

タイプミスがありましたので修正しました。ご指摘ありがとうございます!(2015/9/13)