Ruby技術者認定試験 Silver について1

 Ruby技術者認定試験 Silver まとめ

 

== === eql? equal?関係

 

https://techracho.bpsinc.jp/hachi8833/2018_07_04/58707

https://www.sejuku.net/blog/14634

 

 

def foo (a, *b)
  p a
end
foo(1,2,3,4)
  • B.1

 *がついた引数は可変長引数(rest引数)です。fooメソッドでは最低1つの引数を必要とします。第一引数は変数aで得ることができ、残りの引数は配列に格納されます。

 

 

puts({"members" => 193, "year" => 2014}.size)
  • D.2

 Hash#sizeはHashの要素の数を返します。

 

問題11. 以下の__(1)__に入る適切な記述を1つ選択してください。

h = {1=>2, 3=>4}
 h.__(1)__
 p h #=>{}

ary = [1, 2]
ary.(1)
p ary #=>[]

  • A.clear

clearメソッドは、空の配列、ハッシュを返します。配列とハッシュで類似の動きをするメソッドについて、clearのほかにも、replaceをおさえておきましょう。

 

 

問題12. 以下の__(1)__に入る適切な記述を2つ選択してください。

a = [1,2,3,4,5]
 p __(1)__ #=>[1,2,3]

 

  • A.a[0…2]
  • C.a.slice(0,3) #ゼロから3つ

 Silver試験では配列の添字演算子[ ]の特徴の理解が要求されます。
a = [1,2,3,4,5]
p a[0] #=>1
負の添字も存在します。-1であれば最後の要素となります。
p a[-2] #=>4
長さを指定する場合
p a[0,2] #=>[1,2]
その他の表記法
p a[0..1] #=> [1,2]
p a[0...1] #=>[1]  #ゼロからゼロまで...はマイナス1となるので。
p a[-2…4] #=>[4.5]
p a[-1…1] #=>
今までの表記は下記、Array#シンタックスシュガーです。

p a.()
p a.(0) #=>1

Array#sliceはArray#[]の別名です。

 

 

 

問題15. 以下のコードにおける4行目io.rewindについて正しい説明を1つ選択してください。

File.open('foo.txt','r') do |io| puts io.gets puts io.read io.rewind p lines = io.readlines end
 

IO#rewindはファイルポインターを先頭に移動させます。
IOクラスでは、IO#rewindの他に、 seek、gets、read、readlineなどのインスタンスメソッドをドキュメントでチェックしておく必要があります。

 

https://qiita.com/NA070/items/bd0a5295e540e27936b3

 

 

一気に読み込む (size指定して読み込む)

  • io.read

ファイルポインタを移動する

  • io.seek(offsetwhence)

引数offsetには位置を整数で指定する。
引数whenceにはoffsetをどう評価するかを指定する。
■ whenceの値
- IO::SEEK_SET : offsetで指定された位置にファイルポインタを移動する
- IO::SEEK_CUR : offsetを現在の相対位置とみなしてファイルポインタを移動する
- IO::SEEK_END : offsetをファイルの末尾からの相対位置としてファイルポインタを移動する

 

IOクラスオブジェクトからデータを1行読み込む

  • io.gets(rs)
  • io.each(rs)
  • io.each_line(rs)

行の区切りは引数(rs)で指定することができる(デフォルトは"¥n")

返却値には改行文字列を含みます

getsメソッドは入力終わりに達してから更に読込とnilを返す

入力終わりまで言ったかどうかは eof? メソッドで判定

 

IO.readlines(path[, rs])

path で指定されたファイルを全て読み込んで、その各行を要素と してもつ配列を返します。 IO が既に EOF に達していれば空配列 [] を返します。

 

 

 

問題20. 以下のコードを実行したときの出力として適切な物を1つ選択してください。

p File.join("ruby", "exam","silver")

 

  • D.“ruby/exam/silver”

File#joinは定数FILE::SEPARATOR '/'を使って文字列を連結します。

 

 

 

問題22. 以下のコードを実行したときの出力として適切な物を1つ選択してください。

string = "test code"
string.slice(0,4)
p string 
  • B.“test code”

String#slice(nth, len)は文字列のnth目からlen文字の文字列を作って返します。
String#sliceは非破壊的なので、文字列"test code"が表示されます。代りに破壊的なメソッドであるString#slice!を使用すると、"code"と表示されます。 

 

問題24. ハッシュ内にキーが存在するかどうか調べるメソッドの使いかたとして、誤っているものを1つ選択してください。

cc = {"nz"=>"New Zealand", "ru"=>"Russia", 
"ar"=>"Argentina"} 

 

  • B. p cc.contain?(‘nz’)

以下のメソッドはHashがkeyをキーとして持つときはtrueを返します。
Hash#has_key?(key) -> bool
Hash#include?(key) -> bool
Hash#key?(key) -> bool
Hash#member?(key) -> bool

 

 

問題26. 以下のコードを実行して文字列sの単語毎の出現回数を出力させたい。(1),__(2)__に入る最適な組み合わせを1つ選択してください。

s = "To be or not to be, that is the question."\n hash = Hash.new(0)\n s.__(1)__(__(2)__) {|i| hash[i] += 1}\n p hash["be"] #=>2\n 

 

  • C. (1)scan (2)/\w+/

問題のコードでは正規表現パターンにマッチした文字列が繰り返しブロック引数に渡され実行されます。matchが一度しか正規表現によるマッチを行わないのに対し、scanは繰り返しマッチを行います。正規表現の\wは単語構成文字 [a-zA-Z0-9_]の省略記法です。今回は単語をハッシュのキー、出現回数を値として、単語の出現回数に応じて値をインクリメントさせています。

 
 
 

問題27. 組み込みライブラリ、Integer#chr(encoding)についての説明として正しいものはどれか、2つ選択してください。

  • A.引数を指定しなかった場合はエラーが発生する。
  • B.指定されたエンコーディングでselfを正しく解釈できない場合はnilが返される。
  • C.引数で与えられたencodingにおいて、selfを文字コードと見なし、それに対応する一文字からなる文字列を返す。
  • D.指定されたエンコーディングでselfを正しく解釈できない場合はエラーが発生する。

正答:C,D

Integer#chrは文字コードに対応する1文字の文字列を返します。
p 12354.chr(Encoding::UTF_8) #=>“あ”
selfを引数で与えられたエンコーディングで正しく解釈できない場合は、RangeErrorが発生します。

 chr -> String
chr(encoding) -> String

与えられたエンコーディング encoding において self を文字コードと見た時、それに対応する一文字からなる文字列を返します。 引数無しで呼ばれた場合は self を US-ASCII、ASCII-8BIT、デフォルト内部エンコーディングの順で優先的に解釈します。

 

 

問題28. 以下のプログラムがerrorと出力する場合__(1),(2)__に入る最適な組み合わせを1つ選択してください。

s = "foo"
 ___(1)___
 s[4] = ?b
 ___(2)___
 puts "error"
end
 
  • A. ___(1)___は「try」、___(2)___は「catch NameError」である
  • B. ___(1)___は「try」、___(2)___は「catch IndexError」である
  • C. ___(1)___は「begin」、___(2)___は「rescue NameError」である
  • D. ___(1)___は「begin」、___(2)___は「rescue IndexError」である

 

正答:D

 

Rubyの例外処理の書き方を以下に示します。
begin
<例外が起こる可能性のある処理>
rescue => <例外オブジェクトが代入される変数>
<例外が起こった場合の処理>
end
Silver試験では、発生する例外の種類と処理に関しての知識が問われます。

 

*書籍で要確認する。 

 

問題29. 以下のコードを実行したときの出力として適切な物を1つ選択してください。

ary = []
ary << 1 && false
true || ary << 2
false && ary << 3
false || ary << 4
p ary
 
  • A. [1, 4]

論理演算子の評価方法について、&&演算子においては左辺が真と評価されたときのみ右辺も評価されます。同じように||演算子においては、右辺が評価されるのは、左辺が偽と評価された場合です。

 
 *書籍で要確認する。 

問題31. 以下のコードを実行したときの出力として適切な物を1つ選択してください。

foo = [1,2,3]
bar = foo
baz = foo.dup

bar[3] = 4
p foo
p bar
p baz

 

C.

[1,2,3,4]
[1,2,3,4]
[1,2,3]
 
foo,barは同じ配列オブジェクトを参照しています。
例題と同じ内容で以下のメソッドを実行すると、以下のようになります。
foo.object_id # barと同じ整数値
bar.object_id # fooと同じ整数値
baz.object_id # 上記2つとは違う整数値
 
 

 

以下がミソ

②では、b[0]の値を変更して、a, b, cそれぞれの値を出力していますが、①で分かった  通りaとbは同じオブジェクトを参照しているため、b[0]の値を変更するとaの出力結果も変わってきます。

cは、a, bと異なるオブジェクトを参照しているため、b[0]の値を変更してもcの値の出力結果には影響が出ないというわけです。

このようにして、dupメソッドは値をコピーして新たにオブジェクトを作成するメソッドなのです。

問題32. テキストファイルを読み込んだファイルオブジェクトから一行ずつ読み込み表示したい。目的に一致するIOクラスのメソッドを2つ選択してください。

  • A.readlines
  • B.read
  • C.gets
  • D.readline
  • E.find

正答:C,D

IO#getsとIO#readlineはファイルオブジェクトから一行読み込んで、読み込みに成功した時には

その文字列を返します。IO#getsとIO#readlineの違いはEOFに到達した時の振る舞いのみです。

IO#getsはnil, IO#readlineはEOFErrorを返します。

 

 

問題33. 以下のコードを実行したときの出力として適切な物を1つ選択してください。

str = "a,b,c,d"
p str.split(/,/, 2)
 
  • A.[“a”, “b,c,d”]
  • B.[“a”,“b”,“c”,“d”]
  • C.[“a”, “b,c,”,“d”]
  • D.“abcd”

正答:A

String#splitメソッドは引数で指定した特定の文字列を区切り文字として、文字列から配列を

生成します。また、第二引数で生成される配列の要素数を指定することもできます。

 

問題34. 以下のコードを実行したときの出力として適切な物を1つ選択してください。

class Object
 def greeting
 print "How are you?"
 end
end

[1,2].greeting

 

  • C.How are you?

正答:C

ArrayクラスはObjectクラスを継承しています。Rubyでは組み込みクラスを含め定義済みのクラスに対してメソッドを追加することができます。また追加だけではなく既存のメソッドを書き換えることもできます。

問題36. 以下のコードを実行した際の出力として正しいものを選択してください。

"a".upto('f').to_a 
  • B.[“a”, “b”, “c”, “d”, “e”, “f”]

 

問題37. 以下のコードを実行した時にIOErrorが発生した。理由として考えられるものはどれか1つ選択してください。

File.open("foo.txt") do |io|
 io.write(Time.now.strftime("%Y/%m/%d"))
end
  • C.読み込みモードでファイルが開かれているため

 

 モードを明示的に指定しない場合、読み込みモード"r"でファイルを開きます。そのため、エラーが発生しています。選択肢Bの場合は、IOErrorではなくErrno::ENOENT(システムコールに依存したエラー)を発生させます。例題では、読み込みモードを"w"として開いた場合のファイルの内容は、Time.nowで得た現在時刻を指定したformat文字列で出力したものになります。(例:2015/06/07) 
以下、ファイルオープン時のモード一覧を示します。
“r” 読み込みモード
“w” 書き込みモード。ファイルが存在していればファイルを空にする。
“a” 書き込みモード。ファイルが存在していれば、ファイルの末尾から追記する。
“r+” 読み書き両用モード。ファイルの先頭から読み書きを行う。
“w+” 読み書き両用モード。ファイルが存在していればファイルを空にする。
“a+” 読み書き両用モード。ファイルの末尾から読み書きを行う。

 

 

問題38. 次のメソッドでDirクラスのクラスメソッドではないものをすべて選択してください。(2つ選択)

  • A.Dir.rmdir
  • B.Dir.basename
  • C.Dir.pwd
  • D.Dir.extname
  • E.Dir.getwd

正答:B,D

 

 

 

問題40. 下のコードを実行した時の出力に対して__(1),(2)__に入る最適な組み合わせを1つ選択してください。

p "100,200,300,400,500".___(1)___.___(2)___

[出力]"100\n200\n300\n400\n500"

  • A.(1)split(",") (2)join("\n")
  • B.(1)to_a(",") (2)join("\n")
  • C.(1)split(",") (2)concat("\n")
  • D.(1)concat(",") (2)join("\n")

正答:A

 String#splitと対になる動作をするものにArray#joinがあります。
例題ではカンマ区切りになっていた文字列を改行区切りの文字列で出力しています。

 

問題42. 以下のコードを実行した時の正しい出力結果を1つ選択してください。

numbers = [3,89,40,39,29,10,50,59,69]
 num = numbers.inject do |i,j|
 i > j ? i : j
end
p num
 
  • A.89
  • B.40
  • C.10
  • D.59

 

 正答:A

inject (Enumerable)は前回のブロックの戻り値をブロックに渡して繰り返し実行します。
例題では条件演算子を使い、2つの整数値を比較しより大きな値を取り出しそれをブロックに渡しています。

条件演算子(文法)
式1 ? 式1が真だった場合の値 : 式1が偽だった場合の値

条件演算子では条件式を評価し、真(true)だった場合には真の時の値を、偽(false)だった場合には偽の時の値を式全体の値ととして返します。

 

i > j ? i : j

 https://www.sejuku.net/blog/19219

問題43. 以下のコードを実行した時の正しい出力結果を1つ選択してください。

p String.instance_methods.grep(/strip/) 
  • A.[:strip, :lstrip, :rstrip, :strip!, :lstrip!, :rstrip!]
  • B.nil
  • C.[:strip]
  • D.[]
  • E.エラーが発生

正答:A

 Enumerable#grepではパターンにマッチする要素を配列にして返します。例題ではStringクラスのインスタンスメソッドで正規表現/strip/の文字列に一致するものを配列で返します。

 

問題46. 以下の出力になる時の___(1)___に入るものとして適切なものを1つ選択してください。

class Foo
 ___(1)___= 0
 def self.count
 ___(1)___ += 1
 end
end

class Bar < Foo
end
puts Foo.count
puts Bar.count


[出力]
1
2

 

  • A.num
  • B.@num
  • C.@@num

 

正答:C

 

 

問題48. 以下のコードを実行した時の正しい出力結果を1つ選択してください。

numbers = (1..20).to_a
p numbers.detect{|x| x % 5 == 0}
 
  • A.nil
  • B.10
  • C.5
  • D.20
  • E.[5,10,15]

 

正答:C

 Enumerable#detectメソッドは要素に対してブロックを評価した値が真になった最初の要素を返します。例題では1~20までの数字に対して一番最初の5の倍数を求めていますので正解はCです。Enumerable#findを使っても同様の結果になります。

 

findも同様の結果を返す。

 

問題49. 以下のコードを実行した時の出力結果として正しいものを1つ選択してください。

class NonasciiError < StandardError
end
File.open("sample.txt") do |io|
  io.each_line do |str|
    begin
      raise(NonasciiError, "non ascii character detected") unless str.ascii_only?
    rescue => ex
      puts "#{ex.message} : #{str}"
    end
  end
end

 

  • A. non ascii character detected : ルビーアソシエーション
    non ascii character detected : るびー

raise関数によって明示的に例外を発生させることができます。例題ではString#ascii_only?を使いテキストにASCII文字以外が使われている場合には例外を発生させています。例外処理の基本形は問題28の解説を参照してください。

 

 

 

 問題50 10進数で10を表すものを2つ選択してください。

  • A.0xA
  • B.0xFF
  • C.012
  • D.077
  • E.0x10

正答:A,C

 

 0xAは16進数、012は8進数です。いずれも10進数では10となります。
puts "#{0xA}" => 10
puts '#{012}' => #{012}   ダブルクォーテーション内では式展開されますが、シングルクォーテーションでは式展開が行われません。