REx模擬試験誤答一覧 その5
82点。 徐々に点数も安定してきた。
問5: class M::C
ここに質問を投げてみた。
Ruby - class A::Bとクラス定義を行ったとき、クラスBはクラスAのネストの中にあると考えて良いのか。|teratail
結論は
問7: 実行オプション-l
実行オプション-l
はload_file で、require, load
がなされたときに探し出すディレクトリを指定する。Rubyはこのディレクトリを4か所から探し出し、load_fileで指定するのは、定数$LOAD_PATH
にセットされる最初に探し出す場所。
ここになかった場合、環境変数RUBYLIB
のディレクトリを見に行く。
問27: クラス変数のスコープ
class C class << self @@val = 10 end end p C.class_variable_get(:@@val)
この問題に関して勘違いしていることがあって、クラス変数のスコープに関しては厳然としたルールが定まっていた。
クラス変数は、その場所を囲むもっとも内側の(特異クラスでない) class 式または module 式のボディをスコープとして持ちます。
変数と定数 (Ruby 2.6.0 リファレンスマニュアル)
つまり、特異クラス(メタクラス)をクラス定義内で定義した場合には参照可能だが、外側で定義した場合は参照不可能という変わった状態が発生しうる。
class Foo @@foo = 'Class Variable' class << Foo def class_method_a @@foo end end def bar puts @@foo end end class << Foo def class_method_b @@foo end end p Foo.class_method_a # "Class Variable" p Foo.class_method_b # scope.rb:15:in `class_method_b': uninitialized class variable @@foo in Object (NameError)
では、外側の特異クラスでクラス変数を再定義した場合はどうか。
class Foo @@foo = 'Class Variable' class << Foo def class_method_a @@foo end end def bar puts @@foo end end class << Foo @@foo = 'class_variable redefine' def class_method_b @@foo end end p Foo.class_method_a # "class_variable redefine" p Foo.class_method_b # "class_variable redefine"
クラス定義内と特異クラスの定義内で同じ変数を共有していることがわかる。
問29: alias
aliasの設定のとき、リテラルORシンボルで定義するのは合っているが,
で区切る必要はない。
ただし、メソッド定義内でaliasを設定するときは、alias_method
を用い「文字列かシンボル」で指定し、,
で名前を区切る必要がある。
問36: インスタンス変数のプロパティの設定
インスタンス変数をinitializeメソッドで定義しなくても、attr_accessor(およびreader, writer)をセットすればインスタンス変数として値を保持してくれる。書き込みの際に変数を初期化して、以降インスタンス変数として使えるということのようだ。
class Module (Ruby 2.6.0 リファレンスマニュアル)
問50: YAML to json
YAMLとjsonはそれぞれ読み込み用(format -> Hash)のメソッドが
YAML.load(str/io) JSON.load(str) JSON.parse(str)
YAMLはioオブジェクトも引数に指定できるのに対して、jsonはそれが出来ない。
それぞれの出力用のメソッドは
YMAL.dump(obj) JSON.dump(obj) obj.to_json # Stringクラスのメソッド
となっている。出力はどちらもdump
が使える。YAMLに関してはload
のほかに、自分で普段使っているparse
が使える点に注意。
CSVはこの2つとはやや異なる取り扱いをする。
読み書きの選択はCSVファイルをオープンした後、オプションで選択する。
CSV.open(filename, mode = 'r', opritons = {}){|csv| ... } CSV.open(fielname, mode = 'w' options= {}){ |csv| ... }
一方読み込み専用のメソッドも存在する。
CSV.read(filename) CSV.readlines(filename)