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"}