instance_methods(nil)は何を返しますか
instance_methodsは,あるクラスのオブジェクトが持つメソッドを
返しますが,instance_methods(nil)は,スーパークラスから引き継いだ
ものではなく,そのクラスで初めて定義されたメソッドを返します.
randがいつも同じ乱数列を出しますが
randは,プログラムが実行される度に同じ乱数列を生成します.
異なる乱数列を生成させるためには,srandで毎回異なる乱数の
種を与えてやる必要があります.srandを引数なしで呼ぶと,その時の
時間を種にしますので,異なる乱数列を生成させることができます.
def sample(n, m)
if m.zero?
[]
else
s = sample(n-1, m-1)
t = rand(n+1)
s.concat s.include?(t) ? n : t
end
end
再帰形でなく書けば,次のとおりです.
def sample(n, m)
s = []
((n-m)...n).each do |j|
t = rand(j+2)
s.concat s.include?(t) ? j+1 : t
end
s
end
Fixnum,true,nil,falseが
即値だということですが,参照との違いは何ですか
Fixnumのインスタンスは常に同じものになりますので,
インスタンス変数を定義した場合には,それも同じものを示すことに
なります.
nilとfalseはどう違いますか
nil.methods - false.methodsと
false.methods - nil.methodsを表示してください.
nilを値として持つことができませんが,
falseを持つことはできます.
true,falseを,そうでない
時は値かnilを返すようにすることが好まれます.
?のつくメソッドは,真偽を返すのが一般的ですが,
そうでないものもあります.
open("example", "r+").readlines.each_with_index{|l, i|
l[0,0] = (i+1).to_s + ": "}
とやっても,exampleに行番号がつきません.
ファイルを書き換えているのではなく,readlinesで読み込んだ文字列を
変えているだけです.ファイルに書き戻してやらなければいけません.
io = open("example", "r+")
ary = io.readlines
ary.each_with_index{|l, i| l[0,0] = (i+1).to_s + ": "}
io.rewind
io.print ary
io.close
-i,もしくは,組込み変数$-i
に""を指定することにより,同じ名前のファイルに書き戻すことができます.
$ ruby -i -ne 'print "#$.: #$_"' example
元のファイルを残しておきたければ,-i.bakなどとしてください.
open('file', 'w').print "This is a file.\n"
system 'cp file copy'
とやったのでは,コピーする時にfileに内容がフラッシュされて
いません.きちんとcloseしてからコピーしましょう.
f = open('file', 'w')
f.print "This is a file.\n"
f.close
system "cp file copy"
lessに文字列を渡したのですが,表示されません
f = open '|less', 'w'
f.print "abc\n"
とやっても,直ちに終了してしまい,lessで眺めることができません.
closeしてやると,そこでlessの終了を待ちます.
f = open '|less', 'w'
f.print "abc\n"
f.close
最初の行は,f = IO.popen 'less', 'w'としても同じ結果となります.
Fileオブジェクトはどうなりますか
open("file").readというように参照されないFile
オブジェクトは,次のガーベッジコレクションでcloseされて
捨てられます.
closeしないのは気持ちが悪いのですが
Fileオブジェクトは,GCで自動的にクローズ
されますが,明示的にクローズするには,次の3つの構文から選んで下さい.
(1)
a = open "file"
begin
a.each {|l| print l}
ensure
a.close
end
(2)
IO.foreach("file") {|l| print l}
(3)
IO.readlines("file").each {|l| print l}
Dir.glob("*").filter{|f| [File.mtime(f), f]}.
sort{|a,b| b[0]<=>a[0]}.filter{|e| e[1]}
とすると,カレントディレクトリの".",".."以外のファイルを更新時間の
新しい順にソートした配列を返します.更新時間の古い順にソートする
なら,sortの後ろのブロックはなしにしても,いいですね.
Dir.glob("*").sort{|a,b| File.mtime(b)<=>File.mtime(a)}
でもソートすることができますが,比較する度にファイルにアクセスして
更新時間を調べますので,ソートするのに時間がかかります.
freq = Hash.new(0)
open("file").read.scan(/\w+/){|w| freq[w] += 1}
freq.keys.sort.each {|k| print k, "--", freq[k], "\n"}
trueになります
nilとfalseだけが偽で,それ以外はすべて真に
なります.文字列が空かどうかを知るには,""と比較,empty?を使う,
lengthを0と比較するなどの方法があります.
ary.filter{|f| [f.downcase, f]}.sort.filter{|e| e[1]}
とします.downcaseで等しくなった場合に,元の文字列で比較を行うのが
tipsです.
"abcd"[0]は,何を返しますか
1 while a.sub!(/(^[^\t]*)\t(\t*)/){$1+' '*(8-$1.size%8+8*$2.size)}
1 while a.sub!(/\t(\t*)/){' '*(8-$~.begin(0)%8+8*$1.size)}
a.gsub!(/([^\t]{8})|([^\t]*)\t/n){[$+].pack("A8")}
Regexp.quote('\\')で,エスケープされます.
gsubを使う場合には,gsub(/\\/, '\\\\')では,置換文字列が
構文解析で一度'\\'に変換され,実際に置き換えるときにもう一度'\'と
解釈されるので,
gsub(/\\/, '\\\\\\')とする必要があります.\&がマッチ文字列を
あらわすことを使えば,gsub(/\\/,'\&\&')と書けます.
gsub(/\\/){'\\\\'}とブロックを使う形にすれば,エスケープが1回しか
解釈されませんので,求める結果が得られます.
subとsub!はどう違うのですか
subの場合はレシーバの状態は変化しません.文字列のコピーが
作られ,それに置換がほどこされて(置換が必要なければそのまま)返されます.
sub!ではレシーバそのものが変更されます.変更がない時には
nilが返されます.
sub!のようにレシーバの状態を変化させるメソッドを
破壊的メソッドと
呼びます.Rubyでは同名のメソッドで破壊的なものとそうでないものがある場
合,破壊的なメソッドには慣例的に!をつけます.
def foo(str)
str = str.sub(/foo/, "baz")
end
obj = "foo"
foo(obj)
print obj
# -> "foo"
def foo(str)
str = str.sub!(/foo/, "baz")
end
foo(obj)
print obj
# -> "baz"
sub!のように破壊的なメソッドは予期しない効果をもたらすことがある
ので,使用する場合は十分注意してください.
..と...はどう違いますか
..は終端を含み,...は終端を含みません.
Proc.new,proc,lambdaでProcオブジェクトを作れば,
関数ポインタのような働きをさせることができます.
threadとforkはどう使い分けるのですか
thread,forkはそれぞれ以下のような特徴を持っています.
forkは重い/threadは軽いforkはメモリ空間を共有しないforkの切替えのタイミングは不正確/threadはもっと不正確threadではスラッシングが起きないthreadはDOSでも動くthreadがなんらかの理由でブロックすると全体が止まるforkとthreadを混ぜるのはよくないようです.
threadはタイムシェアリング方式なので,threadを使
うことによって処理が速くなることはありません.
Marshal.dump obj, io, lev
という形式で行います.ioには書き込み可能なIOオブジェクト,levは
オブジェクトが内容として他のオブジェクトを持っている時に,どこ
までオブジェクトの内容を格納するかを決めます.lev段までオブジェクト
をdumpしてもまだオブジェクトがある時には,そのオブジェクトのdumpは
オブジェクトの参照になりますので,再生した時には,参照が変わって
いるでしょうから,再生できないことになります.levのデフォルトは
100になっています.ioを省略した時には,文字列でdumpされます.
obj = Marshal.load io
または,
obj = Marshal.load str
という形式で,ioはdumpしたファイルを読み込み可能でopenしたもの,
strはdumpした文字列を指定します.
begin
(例外が発生しそうな処理)
rescue (例外クラス)
(例外が発生した場合の処理)
ensure
(必ず実行したい処理)
end
begin節で例外が発生するとrescue節が実行されます.
ensure節は例外が発生してもしなくても必ず実行されます.rescue
やensureは省略できます.rescureの後ろに例外クラスが
指定されなかった場合は
StandardErrorが指定されたものとみなされ,StandardErrorの
サブクラスである例外が捕捉されます.
begin節の値です.
$!により参照できます.
発生した例外の種類は$!.typeにより調べることができます.
trapはどのように使いますか
trap("PIPE") {raise "SIGPIPE"}