Ruby Gold模擬試験誤答一覧
あと試験日まで17日にして52/100点というものすごい点数をたたき出しているorz それでも前回の40/100点よりよくなっているのか....
それにしてもRExの問題は模擬試験よりだいぶ難しく作られているように感じる。
問題2: Float, Rational, Complex同士の計算
FloatとFixnum同士の計算はFixnumで、より精度の細かいほうで答えが返される。 また、RationalとComplex同士の計算はComplexで返される。(Complexの方は他の表現方法がないので、これはわかりやすい。)
irb(main):005:0> (1/3r + 2i).class => Complex
しかし、FloatとRational同士の計算の答えは、Floatが返される。 これはRationalの方がより正確であることを考えれば、やや不自然な挙動に感じる。
irb(main):002:0> b = 1/3r => (1/3) irb(main):003:0> b + 0.05 => 0.3833333333333333
問題3: when-caseの比較
case文の比較には===
という特別なメソッドが用いられる。
===
というメソッドは左辺に持ってくるオブジェクトごとに再定義が可能なので、左辺のオブジェクトごとの===
メソッドのオーバーライドを知っておかないと挙動を把握できない。
問題9: 組み込み定数
はじめて聞く名前だったが、「実行環境」の章で扱っていたようだった。 全てがObjectクラスに所属しているという解釈で良いようだ。
名前 | 意味 |
---|---|
STDIN | 標準入力 |
STDOUT | 標準出力 |
STDERR | 標準エラー出力 |
ENV | 環境変数 |
ARGF | 仮想ファイル |
ARGV | 実行引数 |
DATA | END以降の文字列 |
問題10: rescue節での再raise
rescue節での再raiseは救出した例外を再度発生させる。
問題11 : DATA & END
問題10で扱ったばかりだが、DATAはファイルのEND以降をオブジェクトとして扱うための定数である。
問題12 : alias 新名 旧名
メソッド名の変更には以下の2つの方法がある。
alias
新メソッド名 replace 旧メソッド名 の並び方。 文字列で表記する必要はなく、リテラル(そのまま)かシンボルで指定する。
命名変更後は、変更対象のメソッドが再定義されても、変更は適用されない。(つまり命名変更を行った時点から動きが変わらない。) 変更を適用したい場合、新メソッド名で再定義を行う必要がある。
alias_method
Kernel moduleのメソッド。こちらは、シンボルか文字列で定義をし直す。 KErnel moduleのスコープに入って利用する必要があるため、あんまり使われ無さそう。
問題13: クラス変数
クラス変数は特異クラスからもクラスのクラス変数にアクセス出来てしまう。 よって、特異クラスで定義されている特異メソッドからも一番最後に更新されたクラス変数が更新される。
問題17: undef
ここにズバリが書いてあって、undefはスーパークラスに対しても効果を発揮する。 なお、undefに指定するメソッド名はリテラル(そのまま)かシンボルを用いる。
問題18: 多重代入(配列)
配列展開*
がないと代入されないもんだと思っていたら、そうでもなかった。
irb(main):005:0> a,b,c = [1,2,3] => [1, 2, 3] irb(main):006:0> p a 1 => 1 irb(main):007:0> p b 2 => 2 irb(main):008:0> p c 3 => 3 irb(main):009:0> a,b,c = 1,2,3 => [1, 2, 3] irb(main):010:0> p a 1 => 1 irb(main):011:0> p b 2 => 2 irb(main):012:0> p c 3 => 3
数が足らなくても、出来ちゃう
irb(main):006:0> a,b,c,d = [1,2] => [1, 2] irb(main):007:0> p a 1 => 1 irb(main):008:0> p b 2 => 2 irb(main):009:0> p c nil => nil
代入される側が足らなくてもOK!
irb(main):010:0> e,f = [1,2,3,4,5] => [1, 2, 3, 4, 5] irb(main):011:0> p e 1 => 1 irb(main):012:0> p f 2 => 2
問題19: 昇順・降順
昇順にしたい場合は、右側にくる値が「1」か引き算をして正の値がでればよい。
pyons@LAPTOP-SF87NLCB:/mnt/c/Users/broad$ irb irb(main):001:0> x = ['AAAAA','CCC','BBBB'] => ["AAAAA", "CCC", "BBBB"] irb(main):002:0> x.sort{|x,y| x.size - y.size} => ["CCC", "BBBB", "AAAAA"] irb(main):004:0> x.sort{|x,y| x.size <=> y.size} => ["CCC", "BBBB", "AAAAA"] irb(main):005:0> x.sort{|x,y| y.size <=> x.size} => ["AAAAA", "BBBB", "CCC"] irb(main):006:0> x.sort{|x,y| y.size - x.size} => ["AAAAA", "BBBB", "CCC"]
問題24: StringIO
StringIOに関しては既に他の投稿でカバーしている。
1: 文字列をIOオブジェクトと同じように扱える。
IOクラスについて完全に忘れているが、IOクラスはFileクラスのスーパークラスで、標準出力、標準入力、標準エラー出力を扱うためのクラスである。ファイルの位置のポインタを指定して読み込んだり、ポインタの位置をファイルの先頭にするためのオプション定数が存在したするあたりは、IOオブジェクトに似ている。
実際StringIOは「文字列をIOオブジェクトのように扱う」ことを目的に作られた添付ライブラリである旨が教科書でも述べられている。
2 : ファイル入出力専用の文字列である。
それはおそらくIOクラスのことを指している。
3 : IOクラスのサブクラスである。
IOクラスと同じようなインターフェースを持っている旨が述べられているが、IOクラスと直接の継承関係はない。IOクラスは ObjectクラスのDataクラスのサブクラスである。
一方のIOクラスはObjectクラス直下のクラスであり、そのサブクラスにFileの他Basic SocketというIPソケットなどのスーパークラスとなるクラスが継承されている。
4: 文字列をファイルに読み書きできる。
それはIOクラスの仕事。
よって答えは1のみとなる。
問題25: トップレベルに定義するメソッド
トップレベルに定義されたメソッドはObjectクラスのprivateメソッドとして定義される。
問題 29: 多重代入
既に取り扱ったが、配列の多重代入は展開して行われる。
問題 30: freeze
freezeはオブジェクトの変更自体を禁止するもので、「オブジェクトの自己代入」が行われてしまえば、もうその変数に代入されているオブジェクト自体が異なってしまうので、freeze
の意味をなさない。
問題 33: undef
問題17と全く同じ。undefは継承関係を遡って適用される。
問題 34: Module#ancestors
ちょっとした引っ掛け問題。
ancestorsはクラスおよびモジュールがレシーバーのときだけ使える。
今回はメソッドの中で利用なのでselfはオブジェクト
になる。
問題 39: RDoc
別のポストでこれを中心に扱う。
問題41 : Data, DataTime, Time
Time以外はrequrieが必要。
irb(main):004:0> (Time.new - Time.new).class => Float irb(main):013:0> require 'date' => true irb(main):014:0> (DateTime.new - DateTime.new).class => Rational irb(main):015:0> (Date.new - Date.new).class => Rational
問題 42: Fiber
Fiberオブジェクトは1回しかresumeされていないので、yieldで引数"B"を返した後の処理は行われない。
問題 43/45: freeze, dup, clone
freezeについての印象がやたらと薄く、なんでこんな印象薄いんだろうと思っていたら、1/3ページ分しか扱われていなかった。
1 : cloneはfreeze, taint, 特異メソッドなどの情報も含めて、完全な複製を作成する。 2 : dupはfreeze, taint, 特異メソッドなどの情報も含めて、完全な複製を作成する。
class C end c = C.new class << c def method puts "method!" end end c.method # method! d = c.clone d.method # method!
少なくとも、特異メソッドはちゃんとコピーされた。 でもdupは特異メソッドはコピーされない。
class C attr_accessor :variable def initialize @variable = 100 end end c = C.new class << c def method puts "method!" end end c.method # method! d = c.dup d.method
cloneは特異メソッドとtaintとfreezeも含めてコピーされるが、 dupは特異メソッドとfreezeはコピーされず、taintのみがコピーされる。
クラスだけでなく、モジュールもfreeze可能である。
モジュールをincludeしたクラスをfreezeすることは出来ない。
どちらも×で、モジュールだろうがクラスだろうがfreezeすることが可能である。
参照先のオブジェクトもコピーされる。
「Rubyにはdeep copyの機能がない」ことをマーシャルで取り扱ったが、cloneについても例外ではなく、浅いcopyしかできない。
問題 47: Marshalが出来ない条件
マーシャルについて扱った章の冒頭に書いてあった。忘れていただけ。
名前のついていないクラスやモジュール
File, Dir, IOなどシステムがオブジェクトの状態を保持するもの
MatchData, Proc, Threadクラスのインスタンス
特異メソッドが定義された、インスタンス
問題 49: load & require
load
は拡張子の補完を行わず、複数回のロードも可能である。バイナリエクステンションはロードできない。
require
は拡張子の補完を行い、複数回のロードを防ぐ。バイナリエクステンションのロードも可能である。
問題50: Threadの例外
Thread内で例外が発生しても、他のスレッドが(sleepしているスレッドが)生き続けている限り、プログラム自体の終了にはならない。また、エラーメッセージの表示なども行われない。
但し、デバッグモードで実行している場合、実行しているいずれかのスレッドで例外が発生すればメッセージを表示して処理は終了となる