Ruby初學者スレッド Part 9
■ このスレッドは過去ログ倉庫に格納されています
0001紅寶石
2006/11/21(火) 08:33:42マニュアル
http://www.ruby-lang.org/ja/man/
Ruby FAQ
http://ruby-lang.org/ja/man/?cmd=view;name=Ruby+FAQ
逆引きRuby
http://www.namaraii.com/rubytips/
Ruby リファレンスマニュアルの Windows HTML Help版
http://elbereth-hp.hp.infoseek.co.jp/ruby.html
Rubyリファレンスマニュアル刷新計画
http://doc.loveruby.net/
前スレ
Ruby初心者スレッドPart8
http://pc8.2ch.net/test/read.cgi/tech/1159424939/
>>2-10
0075デフォルトの名無しさん
2006/11/25(土) 01:19:34はじめてしった
スクリプトの第一行目は、
#!/usr/bin/ruby -Ku -Ilib
と書いても
#!/usr/bin/ruby "-Ku -Ilib"
とひとくくりにされるわけね・・・
引数が一個だと、「一応は」動いているわけだ
0076デフォルトの名無しさん
2006/11/25(土) 10:18:58違う。そこは実装依存。
Linuxはそうなるというだけで、ほかのUNIXだと適切に解釈してくれるものもある。
0077デフォルトの名無しさん
2006/11/25(土) 14:38:06「shebangでは複数の引数を書くべきではない」
ということ。
どうしても複数の引数を与えたい場合は、>>74のように一ひねりすること。
0078デフォルトの名無しさん
2006/11/25(土) 15:04:54そうなん?
これって、どのレベルで決定されるものなんでしょ?
OS?shell?ruby?
0079デフォルトの名無しさん
2006/11/25(土) 16:19:54MAINスクリプトから,SUBスクリプトに値(オブジェクト)を受け渡ししたいのですが,
いろいろサンプルを読んでもウィジェット側からサブルーチンを呼び出す方法しか無く,
その逆の方法の参考がありません。
Ruby/Tkを子プロセス的というか関数的に使うにはどうしたらよいでしょうか?
#!ruby
# MAIN
require 'sub.rb'
include Submodule
val = String.new
result = sub(val)
resultについての処理
...
__END__
#!ruby
# SUB
moduel Submodule
require "tk"
def sub(val)
v = TkVariable.new(val)
TkRadioButton.new { text 'top'; variable v ; value 'top'; anchor 'w'
pack('side' => 'top', 'fill' => 'x')}
TkRadioButton.new { text 'middle'; variable v ; value 'middle' ; anchor 'w'
pack('side' => 'top', 'fill' => 'x')}
TkButton.new { text 'Quit' ; command 'exit' ; pack }
Tk.mainloop
end
__END__
0080デフォルトの名無しさん
2006/11/25(土) 16:29:48shebang の処理は kernel が行ってるはず
0081デフォルトの名無しさん
2006/11/25(土) 17:43:35openメソッドをwモードでファイルを作成して
どうすればよいのでしょうか?
0082デフォルトの名無しさん
2006/11/25(土) 17:48:31>>1の逆引きRuby見たか?
0083デフォルトの名無しさん
2006/11/25(土) 18:10:10はい。
.writeメソッドではないですし。
0084デフォルトの名無しさん
2006/11/25(土) 18:17:39こんなのではいかが?
http://www.namaraii.com/rubytips/?%A5%D5%A5%A1%A5%A4%A5%EB%A5%A2%A5%AF%A5%BB%A5%B9#l9
ちゃんと見よう
0085デフォルトの名無しさん
2006/11/25(土) 18:42:18すみません。ありがとうございます。無事解決いたしました。
また、続きの質問なのですがこのようなプログラムで実行すると
出力ファイル名が、outputになります。標準入力から入力した文字にしたかったのですが・・・
output = $stdin.gets.chomp
up = File.open("output","w")
"output" を"#{output}" にして式展開すると入力した文字になりますが
#{} をしなくて入力した文字にすることはどうすればよいのでしょうか?
#{}だと面倒なのですが・・
0086デフォルトの名無しさん
2006/11/25(土) 18:44:15"output" のクォートを取ってみな
0087デフォルトの名無しさん
2006/11/25(土) 23:42:37その三者で言えば OS。 shebang 行の解釈はシステムコールがやる。どっちみち77が正しい。
0088デフォルトの名無しさん
2006/11/26(日) 17:07:36そりゃexitしたらそれ以上実行されんわな。
0089デフォルトの名無しさん
2006/11/26(日) 17:20:09module Submodule
require "tk"
def sub(val)
v = TkVariable.new(val)
root = Tk.root
TkRadioButton.new {text 'top'; variable v; value 'top'; anchor 'w'
pack('side' => 'top', 'fill' => 'x')}
TkRadioButton.new {text 'middle'; variable v; value 'middle'; anchor 'w'
pack('side' => 'top', 'fill' => 'x')}
TkButton.new {text 'Quit'; command {root.destroy}; pack}
Tk.mainloop
v.value
end
end
include Submodule
result = sub("")
p result
0090デフォルトの名無しさん
2006/11/26(日) 18:17:060091デフォルトの名無しさん
2006/11/26(日) 18:58:38Rubyスクリプトをある程度書けるようになった人で
GUIがどうしても必要になった人が仕方なく止むに止まれぬ理由で使うのがRuby/Tkだよな
少なくとも、Ruby部分で躓くような人はまだ使ってはイカン
0092デフォルトの名無しさん
2006/11/26(日) 19:19:29文字列中のAをBに、EをFに、MをNに、OをPに 置換したいのですが
どうすればできるのでしょうか?
gsubメソッドだと
string.gsub(/AEMO/,'BFNP') じゃ、AEMOをBFNPと固まった文字列で置換してしまいます。
一度で各文字を置換指定するにはどうしたらよいのでしょうか?
0093デフォルトの名無しさん
2006/11/26(日) 19:30:392. gsub にブロックを渡して、マッチした文字ごとに分岐する処理を書く
3. tr を使う
http://www.ruby-lang.org/ja/man/?cmd=view;name=String#tr
"ABCDEFGHIJKMNOPQRSTUVWXYZ".tr("AEMO", "BFNP") # => "BBCDFFGHIJKLNNPPQRSTUVWXYZ"
0094デフォルトの名無しさん
2006/11/26(日) 21:48:55start = 1000
moji = ""
(0..15).step(3){|i|
moji << #{out[i,3]} + "(" + "#{start.to_i - 150 + i}" + ")" + ","
p moji
}
すみません、7行目に文法エラーと出てしまましたが、どう間違って?
ARA(850),FAF(853),・・・ みたいに表示したく。
そして、最後の文字列の , は削除したいと思っておりますが、それ以前にエラーがでてしまいます。
どうぞよろしくお願いいたします。
0095デフォルトの名無しさん
2006/11/26(日) 21:53:43> moji << #{out[i,3]} + "(" + "#{start.to_i - 150 + i}" + ")" + ","
^^^^^^^^^
ここが違う。
#{} は文字列に変数を埋め込むときに使う。
この場合out[i,3]だけでいい。
↓のようにしても(・∀・)イイ!!。
moji << "#{out[i,3]}(#{start.to_i - 150 + i}),"
0096デフォルトの名無しさん
2006/11/26(日) 21:56:32というか、前者の書き方が見にくいからこその#{}だよな。
0097デフォルトの名無しさん
2006/11/26(日) 22:03:34ありがとうございます!無事できました。
#{}を式展開とだけ覚えていたのですが、文字列中で有効なんですね。勉強になりました。
0098デフォルトの名無しさん
2006/11/26(日) 22:04:36j = start.to_i - 150 + i
moji << "#{out[i,3]}(#{j}),"
埋め込むのは変数やメソッドだけにしてこう書こうぜ
0099デフォルトの名無しさん
2006/11/26(日) 22:53:57括弧やクォートの囲みは浅くしたい
010099
2006/11/26(日) 22:56:110101デフォルトの名無しさん
2006/11/26(日) 23:58:59make_the_file unless Filetest.exist?(file)
file読み込み処理
と
begin
file読み込み処理
rescue Errno::ENOENT
make_the_file
retry
end
ってどっちが「普通」ですか?
前者は Filetest.exist? が毎回必ずディスクを余分に読みますよね
例外を待ち構えて例外が起こったときに対処したほうが素直ですか?
0102デフォルトの名無しさん
2006/11/27(月) 00:25:48俺は上が好み。
0103デフォルトの名無しさん
2006/11/27(月) 00:44:54後者はretryの取り扱いミスが怖いので前者
確かにディスクアクセスが余分で気持ち悪いけどね
本当は後者がウツクシイんだろうな、と思う
0104デフォルトの名無しさん
2006/11/27(月) 00:51:22泣いたことを思い出した
0105デフォルトの名無しさん
2006/11/27(月) 10:03:460106デフォルトの名無しさん
2006/11/27(月) 10:28:050107デフォルトの名無しさん
2006/11/27(月) 10:50:54(-1, 2) で試したところ、(-1, 1) と同じ結果がでてきたのですが・・・
0108デフォルトの名無しさん
2006/11/27(月) 11:44:03普通、Rubyでは一発ではできない。
Rubyの文字列枚挙操作は、1バイトを単位として動作し、日本語2バイト文字列を「1文字」として解釈しない。
が、1バイトの英数字だけならStringのsliceメソッドが使える。
>>106はよくある間違い(というかこれ仕様が意地悪)なので注意。
0109デフォルトの名無しさん
2006/11/27(月) 11:46:36う。すまんボケてた。
後ろ二文字ならslice!(-2, 2)とか、
めんどくさけりゃstr.slice!(-2, str.length)だな。
というかリファレンスのString#slice!を参照
0110デフォルトの名無しさん
2006/11/27(月) 11:48:36仕様で最後のslice(-1, 1) でしか無理ってことかな。
0111デフォルトの名無しさん
2006/11/27(月) 11:50:08$KCODEをきちんと指定+実行コスト度外視だったら、
arr = str.split(//)
arr.pop
str = arr.join
とか。
0112デフォルトの名無しさん
2006/11/27(月) 11:57:28ありがとうございました。無事できました。
日本語でも一発でできるようなメソッド装備すればいいのに。
0113デフォルトの名無しさん
2006/11/27(月) 11:58:15Rubyのstr[-m,n]は「末尾から数えてmバイト目から右→に向かってnバイトを範囲とする」だからね。
直感的には「末尾から数えてmバイト目から左←に向かってnバイト分」だと思うんだが。
>>111
日本語含んだ文字列ではやっぱり正規表現で分割して配列にするしかないのかな。
irb> str="ねこだいすき"
irb> puts str.scan(/(.+?).$/e)
ねこだいす
irb> str2="hoge"
irb> puts str2.scan(/(.+?).$/e)
hog
うーん。
0114デフォルトの名無しさん
2006/11/27(月) 13:01:27<< または + を使って
私は 猫が とても 大好き です という各単語(word)を順次イテレータで追加していくと
str = ""
str << word
で、「私は猫がとても大好きです」という文字列になりますよね。 これを
「です大好きとても猫が私は」のように後ろにあるやつを前にしていきたいのですが・・・
0115デフォルトの名無しさん
2006/11/27(月) 13:07:51そのwordを何で保持してるかに拠るだろ。
Arrayならreverseすればいいし。
0116デフォルトの名無しさん
2006/11/27(月) 16:10:51str[0,0] = prefix
# self[regexp]=val
str[/^/] = prefix
# sub!(pattern, replace)
str.sub!(/^/, prefix)
0117デフォルトの名無しさん
2006/11/27(月) 16:48:04db.root?('hoge')を使うしか。
db['hoge']すると例外が発生してほしいってこと?
0118デフォルトの名無しさん
2006/11/27(月) 17:48:53irb> h=Hash.new
irb> p h['hoge']
nil
これにあわせた動作なんだろうけどな
0119デフォルトの名無しさん
2006/11/27(月) 19:35:52ことがあります。
環境:ruby 1.8.5 (2006-08-25) [i386-linux]
Vine Linux 2.6.16-0vl15
自分は、rubyからshellを呼び出すときShellクラスを使っています。
今やっている事は、あるprogram1で作成したテキストファイルをgnuplot
に読み込ませてグラフを自動生成するというものです。
簡単に例を示すと・・・
#Rubyでの処理
==============
==============
==============
#Shellでの処理
sh = Shell.new
sh.system("program1") #gnuplot用スクリプトscript1生成
sh.system("gnuplot","script1") #epsファイルを出力する
#終了
のようにgnuplotを実行させたいんですが、epsファイルが作成されません
でした。しかし、ターミナルから手動でgnuplot script1を実行すると正常
にepsファイルが出力されたので、恐らくsh.system()を呼び出す時のタイミ
ングの問題かと思うのですが、詳しい方の意見を頂けたらとありがたいです。
ちなみにscript1を作成した状態でsh.system("gnuplot","script1")だけを実
行させると正常にepsファイルが作成されました。また、sh.system("gnuplot",
"script1")の前にsleep()で0.2[sec]ほど待つと正常に出力されるのですが、eps
ファイルを作成する数が多いため時間がかかり過ぎてしまいます。最終的にはル
ープを使用して複数のepsファイルを作成するので。
0120デフォルトの名無しさん
2006/11/27(月) 20:03:02system("program1")
system("gnuplot script1")
とか
`program1`
`gnuplot script1`
じゃダメですか?
0121デフォルトの名無しさん
2006/11/27(月) 20:41:05大きなファイルを扱うのですが、最後の行だけ欲しいのです。
後ろから100バイト読んで、改行コードが無かったらまた100バイト読む。
という感じで出来るかな?と思ったのですが、
「後ろから読み込む」やり方がわからないです。
0122デフォルトの名無しさん
2006/11/27(月) 21:10:250123デフォルトの名無しさん
2006/11/27(月) 21:15:37大きなファイル扱うってかいてるじゃんか。
File#seekで読み込み位置ずらしていくのがベストじゃないの?
0124デフォルトの名無しさん
2006/11/27(月) 21:17:55IO#seek(offset, IO::SEEK_END)
あたりが使えそう…だろうか。
まぁ、めんどいことになるのは確かだ。
0126デフォルトの名無しさん
2006/11/27(月) 22:51:01レシピブックにそういう話が載ってたような気がする
0127121
2006/11/27(月) 23:45:06レシピブック、今手持ちに無いので明日見てみようと思います。
それともう一つ問題が。
無限ループしてる訳では無いのですが、巨大なファイルを扱っているので
C:/workshp/test01.rb:142:in `clear': stack level too deep (SystemStackErro
r)
というエラーが出てしまいます。
これについては、
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/29569
これが参考になったのですが、gc.c(rubyのソースですよね?)を変更しないといけないし、
そのあとコンパイルも必要になるので、私が触れるレベルじゃなさそうです・・・。
何か解決策はありますでしょうか。
0128デフォルトの名無しさん
2006/11/28(火) 01:04:37普通の手法で書いてる限り巨大なファイルとスタックオーバーフローは全くなんの関係もない。
Rubyがstack level too deepと言うのは、Rubyがバグってないかぎりは関数呼び出しの階層が深すぎる場合だけ。
噛み砕いて言うと、関数から関数を呼び出してその関数から関数を呼び出して、ってのを数千回繰り返すと起きる。
つまり自分が書いてるコードが悪いだけだ。
プログラムをよく眺めて考えろ。頭の中で実行してみろ。マニュアルを読め。
ところどころでpして結果を確かめろ。思い込みでコードを書くな。
あと思い込みで質問するな。
0129119
2006/11/28(火) 01:36:42レスありがとうございます。
sh.systemをsystem()もしくは``で置き換えたところ、その症状は改善されました。
ただ、組み込み関数sytem()やバッククオート記法``を使用する場合、Pathはプログ
ラム開始時のカレントディレクトリからの相対パスしか受け付けてくれません。
例えば、
$PWD=top/にいるとき・・・
system("mkdir under/")
system("chdir under/")
system("program1")
system("gnuplot script1")
を行うとtop/under/にではなく、top/にファイル群ができてしまいます。
絶対パスを通せば何とかなりそうですが、後の都合上、相対パスが使いた
い所です。リファレンスなどを当たってみましたが、うまい方法が見付か
りません。カレントディレクトリを変更するのはsystem("chdir under/")
ではダメなのですかねぇ。バッククオートに関しては`cd under/`でエラー
が出てしまい、困っている所です。
度々、質問して申し訳ありません。system()を使った場合、カレントディ
レクトリを変更する方法をご存知の方がいらっしゃいましたら、ご意見を頂
けると助かります。
0130デフォルトの名無しさん
2006/11/28(火) 02:01:40system()で呼び出されるシェル環境は呼び出される都度
別のサブプロセスになるんじゃなかったけか。
#だから2番目のsystem()でカレントディレクトリを変更しても
# 3番目以降のsystem()にはその影響が及ばない。
system("mkdir under; cd under; program1; gnuplot script1")
としてみたらどうよ。
いやおれはRubyは知らないんだけどね。
手元の環境では上のようにして動いたぞ。
0131デフォルトの名無しさん
2006/11/28(火) 02:09:15system の中身はシェルなんだから chdir じゃなくて cd。
cd 自体の返り値を使うわけじゃないんだからバッククォートじゃダメ。
system("mkdir under; cd under; program1; gnuplot script1")
0132デフォルトの名無しさん
2006/11/28(火) 02:10:550133デフォルトの名無しさん
2006/11/28(火) 02:18:03どうせプログラムの構造について考えないなら黙ってshでやりゃすぐじゃね?
覚えてて損はないし、生きてるうちは廃れないだろ。
0134デフォルトの名無しさん
2006/11/28(火) 03:01:14Rubyとのインターフェースもファイル作ってパイプとかリダイレクトとかで済んだりする
0135127
2006/11/28(火) 04:59:41質問の仕方が悪かったですね。ごめんなさい。
ある研究で、巨大なファイルに10万程度の要素があって、その要素を繋げていくプログラムを作っています。
要素を繋げる為にいくつかの関数を用意してるのですが、関数を1000回程度呼び出した所でstack level too deep
になります。
が、こちらとしては正常な動作なので、もっと要素を繋いで行って欲しい。という訳なんです。
Linuxで動かしてみたら2000回程度呼び出したところでメモリ(2G)から溢れてスワップするようになったので、
仰るとおりプログラムを見直してみようと思います。
Windowsでは、stack level too deepを回避する手段は無さそうですね。
0136デフォルトの名無しさん
2006/11/28(火) 06:24:31再帰を非再帰の繰り返しに変更してみな
0137119
2006/11/28(火) 09:43:00レスありがとうございました。教えて頂いた方法で解決しました。
解説をして頂いて、どこが問題なのか理解できました。
fork()は、サブプロセスが立ち上がることは知っていたんですが、
system()がサブプロセスになることを知りませんでした。
>>133,134
確かに、最初からshellでやった方が楽だったような気がします。
Rubyで行う処理もあり、shellをRubyから呼び出した方が手っ取
り早いかなぁと最初は思っていたので。
この度は、お手数をお掛けしました。m(_ _)m
0138デフォルトの名無しさん
2006/11/28(火) 11:47:14require 'fileutils'というのもあるがな。
0139デフォルトの名無しさん
2006/11/28(火) 11:54:220140デフォルトの名無しさん
2006/11/28(火) 18:02:27再度書くがスタックオーバーフローが起こるのは自分の責任。
そもそもスタックがあふれるようなコードを書くべきでないだけの話。
正常な動作というのも勝手な思い込み。
WindowsもLinuxもその他色々もスタックは有限。
書き方が悪ければいずれにせよいつか起こる。
起こるまでの時間が短いか長いかの違いがあるだけ。
0141デフォルトの名無しさん
2006/11/28(火) 18:10:240142デフォルトの名無しさん
2006/11/28(火) 18:11:460143デフォルトの名無しさん
2006/11/28(火) 18:29:17行番号がループする
って話をどっかで聞いた。RHGだっけ。
0144デフォルトの名無しさん
2006/11/28(火) 18:37:08Windowsなプラットフォームで、実際に使えるスタックを十分使わな
いうちにstack level too deepになってしまうという問題が…(略)
って話が。
0145デフォルトの名無しさん
2006/11/28(火) 19:13:230146デフォルトの名無しさん
2006/11/28(火) 19:27:06それは本質ではない。
安直にスタック食い潰して死亡するコードはイクナイという話。
0147デフォルトの名無しさん
2006/11/28(火) 21:12:05プログラムを作成しています。
流れとしましては、
50万行ファイルオープン
↓
指定された5万行を配列に格納。
↓
ファイルクローズ
を考えているのですが、配列に5万行を入れて作業するのと
5万行に分割したファイルを読み込むのとではどちらが軽く処理できるのでしょうか?
しょうもない質問ですが宜しくお願いします。
0148デフォルトの名無しさん
2006/11/28(火) 21:14:19しょうもないと思うなら自分で両方実装してベンチとれや
0149デフォルトの名無しさん
2006/11/28(火) 22:04:28とか言ってみる
0150デフォルトの名無しさん
2006/11/28(火) 22:41:520151デフォルトの名無しさん
2006/11/28(火) 22:50:400152デフォルトの名無しさん
2006/11/28(火) 22:58:03というような解説はあってもいいな
0153デフォルトの名無しさん
2006/11/28(火) 23:41:05再帰。
0154デフォルトの名無しさん
2006/11/28(火) 23:49:51入門書では見たことないな
その辺のフォローはあってもいいよね
0155デフォルトの名無しさん
2006/11/29(水) 01:30:450156デフォルトの名無しさん
2006/11/29(水) 07:30:22関数定義もサブルーチンからのリターンもできない言語か
ループは大丈夫だとしても、キツいなw
gotoまみれになりそうだ
配列で仮想スタック作って自前で管理すれば
サブルーチンを扱えるかも知れんが
それはそれでどうなんだろうw
0157デフォルトの名無しさん
2006/11/29(水) 08:06:160158デフォルトの名無しさん
2006/11/29(水) 12:09:240159デフォルトの名無しさん
2006/11/29(水) 13:27:26require 'tk'
p Tk.getOpenFile
だとルートウィジェットが表示されてしまいます。
Tk.messageBox(:icon=>'warning', :type=>'ok', :message=>"Hello")
の場合は都合よくルートウィジェットは表示されないのですが,
同じようにできないだろうかと思ってます。
0160デフォルトの名無しさん
2006/11/29(水) 13:28:39本当はパイソンらしい。
0161デフォルトの名無しさん
2006/11/29(水) 14:33:42Tk.root.withdraw
0162デフォルトの名無しさん
2006/11/29(水) 15:03:36Thanks
0163デフォルトの名無しさん
2006/11/29(水) 17:08:46指導教官はぜんぜん言語名をまともに呼んだことがなかった。
「ぺいとん」とか「ぴてぃおん」とか。
0164デフォルトの名無しさん
2006/11/29(水) 17:17:30rubyで、画像に文字列を表示したいのですが(サウンドノベルゲームみたいなものの、メッセージが表示される枠のイメージ)
また、複数音声のファイル(mp3など)を、ランダムで読み込んで再生といったことをしたいのですが
参考になるようなところお願い致します。。。
vrubyのTIP系はどこをあたればよいのかわからず
0165デフォルトの名無しさん
2006/11/29(水) 17:55:18そういうのは、Ruby/SDLとか、Miyakoとか使うんじゃない?
0166デフォルトの名無しさん
2006/11/29(水) 18:29:38プログラムの関係でvrubyだけで実装しようとしております。
vrubyでの実装方法などとかはないでしょうか?
0167デフォルトの名無しさん
2006/11/29(水) 19:59:40まあ一度、MIyako使ってみろ。
Windowsでもちゃんと動く。
0168デフォルトの名無しさん
2006/11/29(水) 20:02:00SWin::Windowのメソッドをみろ。
使い方は、vr/をdopaintで検索すれば概ねわかるだろ。
音声関係は、VisualuRubyの守備範囲じゃなかろう。
0169デフォルトの名無しさん
2006/11/29(水) 20:28:53gem environment
とすると、
$RUBYLIB/rubygems/custom_require.rb:35:in `require': No such file to load -- sources (LoadError)
とでてしまいます。
何かヒントでもいいので、ご教授よろしくお願いします。
0170デフォルトの名無しさん
2006/11/29(水) 21:01:06ruby/gems/1.8/gems/sources-0.9.0
とか。
0171169
2006/11/29(水) 21:12:16ないです。
0172デフォルトの名無しさん
2006/11/29(水) 21:23:50ちゃんと用意しろ。
0173デフォルトの名無しさん
2006/11/29(水) 21:26:36ありがとうございました。やれるだけやってみます。
0174169
2006/11/29(水) 22:04:03■ このスレッドは過去ログ倉庫に格納されています