トップページ⇒tech
1001コメント311KB

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
0056デフォルトの名無しさん2006/11/23(木) 21:49:28
ハッシュで表引きするところが肝なのであとはバリエーションでしかないけど、
こんなのも。

(hのキーが?aとかの場合)
require 'enumerator'
"aabdc".enum_for(:each_byte).map{|c| h[c]}

(hのキーが"a"とかの場合。Ruby 1.9だと ?a == "a" だっけ?)
"aabdc".split(//).map{|c| h[c]} # //は空の(中に1文字もない)正規表現

# irbから動かしてString.each_charがないと騒いだのは秘密。
# ActiveSupportめ。

0057デフォルトの名無しさん2006/11/23(木) 21:54:31
define_method でブロックを受け取るメソッドを定義したいんですけど、なんとかなりませんか?
よろしくおねがいします。
0058デフォルトの名無しさん2006/11/23(木) 21:59:22
それはこっちのセリフだ
0059デフォルトの名無しさん2006/11/23(木) 22:05:29
書きかけの自作メール振り分けプログラムにこんなの(以下は断片)があった。

def register_action(sym, &block)
__send__(:define_method, sym) do |*options|
options = options.shift || {}
block.call(options)
end

register_action(:to_folder) do |options| ... end

引数の受け取り方になんか制限つきそうな気が……

0060デフォルトの名無しさん2006/11/23(木) 22:26:47
>>59
トン! なるほどん
0061デフォルトの名無しさん2006/11/23(木) 23:21:30
>>55
ありがとうございました。
時間も半分以下に短縮できました。
0062デフォルトの名無しさん2006/11/24(金) 00:32:00
Mac板にRubyスレないのでここでいいのかな?

まったくの初心者なんですけど(;・∀・)
ターミナルに ruby ファイル名.rb でリターン押しても
ruby: No such file or directory -- ファイル名.rb (LoadError)
ってなります ファイルの保存場所とかにルールとかでもあるのですか?
0063デフォルトの名無しさん2006/11/24(金) 00:44:18
>>62
カレントディレクトリは確認した?
pwd
0064デフォルトの名無しさん2006/11/24(金) 00:50:38
>>63
カレントディレクトリ!?
すいませんほんとに初心者なんで…絶対パスの事かな

仮にデスクトップにそのファイルがあるならばそれを指定しなければダメと言うことですか?
ターミナル自体始めて動かしたもので
0065デフォルトの名無しさん2006/11/24(金) 01:10:44
>>63
ヒントサンクス

おお 自己解決しました Ruby自体の問題ではなくターミナルの問題でした ターミナルちっと勉強するかorz
ファイルの場所をちゃんと指定して大丈夫でした

0066デフォルトの名無しさん2006/11/24(金) 03:09:21
MacならファイルをFinderからターミナルにドロップすれば絶対パスが出てくる。
0067デフォルトの名無しさん2006/11/24(金) 11:56:39
>>65
Rubyに限らず,Macを使いこなすにはターミナルの使い方(bash シェルの使い方)に詳しくなっておくと便利だよ。
かくいう自分は,ターミナル上でRubyを楽しんでるマカーです。
ちょっとした日常の繰り返し作業も,AppleScriptやシェルスクリプトではなくRubyスクリプトを書いて処理してます。
0068デフォルトの名無しさん2006/11/24(金) 15:07:23
スクリプトファイルの冒頭に、
#!/usr/bin/ruby -Ku -Ilib
とかくとエラーになる。ただ、
#!/usr/bin/ruby -Ilib -Ku
と、順序を変えると大丈夫。コマンドラインだと順序関係なく動くんだけど…
何か制約があるの?それとも前者だとオプション解釈上問題でも生じてる?
0069デフォルトの名無しさん2006/11/24(金) 16:42:45
~$ ruby "-Ke -Ilib"
ruby: invalid option - (-h will show valid options) ←たぶんこのエラーが出たはず
~$ ruby "-Ilib -Ke"
ruby: Interrupt   ←エラーなし、終了のためにここでEOF
~$

スクリプトの第1行目(俗称shebang)では、複数の引数は解釈が保証されない。
たとえばLinuxでは「空白後をひとまとめにした1個の文字列」として渡される。

#!/usr/bin/env ruby -Ke がうまく動作しないのもこれが理由。

ということで、「Rubyでは-Kオプションを最初以外に書いておくとたまたま動く」が正解。
0070デフォルトの名無しさん2006/11/24(金) 16:48:37
補足。

Rubyの場合、起動したインタプリタが改めて#!行を自分で解析して
自前である程度は処理してる。

$ cat hoge
#!/bin/sh -x
echo "$@"
$ ruby hoge
とかやると、rubyがshをexecする。
0071デフォルトの名無しさん2006/11/24(金) 17:15:45
perl.pl
---------------------
#!/usr/bin/perl
die "OOPS! IT'S PERL!"
---------------------

~$ ruby ./perl.pl
OOPS! IT'S PERL! at ./perl.pl line 2.


なにこの素敵無駄機能
0072デフォルトの名無しさん2006/11/24(金) 18:05:41
>>69
判りやすい解説thx。-KuIlib としてやったらうまくいった。
-IlibKuだとダメみたい。libじゃなくてlibKuディレクトリを探しにいっちゃうんだろうなぁ。
こんなことドキュメントに書いてあったかな…。

くっつける処理が謎だ。普通にくっつけたら、
先の例、前者のほうが「たまたま」動きそうなもんだが…。

それと、-Cと-Iを同時指定とかしたいときはどうするんだろう…?
0073デフォルトの名無しさん2006/11/24(金) 18:40:46
>71
__END__(Perlでもスクリプト終端)を
組み合わせると混ぜコード書けるが
素敵過ぎてオススメできないんだぜ
0074デフォルトの名無しさん2006/11/24(金) 21:36:07
>>72
shebangに書かない。
シェルスクリプトから起動するようにする。

#!/bin/sh
ruby <好きなだけオプション> <Rubyスクリプトファイル>

こんな感じ。
あんまりよろしくないけど。
ってか、そんなにオプション付けたくなるようなことってあるか?
俺の場合は、あって-Kくらいだけどなー。
-lも-CもRubyのスクリプト内でできるしな。厳密には意味が違うかもしれんが。
0075デフォルトの名無しさん2006/11/25(土) 01:19:34
>>69
はじめてしった

スクリプトの第一行目は、
#!/usr/bin/ruby -Ku -Ilib
と書いても
#!/usr/bin/ruby "-Ku -Ilib"
とひとくくりにされるわけね・・・

引数が一個だと、「一応は」動いているわけだ
0076デフォルトの名無しさん2006/11/25(土) 10:18:58
>75
違う。そこは実装依存。
Linuxはそうなるというだけで、ほかのUNIXだと適切に解釈してくれるものもある。
0077デフォルトの名無しさん2006/11/25(土) 14:38:06
間違いなく言えることは、
「shebangでは複数の引数を書くべきではない」
ということ。
どうしても複数の引数を与えたい場合は、>>74のように一ひねりすること。
0078デフォルトの名無しさん2006/11/25(土) 15:04:54
>>76
そうなん?
これって、どのレベルで決定されるものなんでしょ?
OS?shell?ruby?
0079デフォルトの名無しさん2006/11/25(土) 16:19:54
Ruby/Tkをサブルーチン的に使いたいので教えて下さい。概要は後記のように,
MAINスクリプトから,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:48
>>78
shebang の処理は kernel が行ってるはず
0081デフォルトの名無しさん2006/11/25(土) 17:43:35
開いたファイルに文字を書き込む場合はどうしたらよいのでしょうか?

openメソッドをwモードでファイルを作成して
どうすればよいのでしょうか?
0082デフォルトの名無しさん2006/11/25(土) 17:48:31
>>81
>>1の逆引きRuby見たか?
0083デフォルトの名無しさん2006/11/25(土) 18:10:10
>>81
はい。
.writeメソッドではないですし。
0084デフォルトの名無しさん2006/11/25(土) 18:17:39
>>81
こんなのではいかが?
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
>>84
すみません。ありがとうございます。無事解決いたしました。

また、続きの質問なのですがこのようなプログラムで実行すると
出力ファイル名が、outputになります。標準入力から入力した文字にしたかったのですが・・・

output = $stdin.gets.chomp
up = File.open("output","w")

"output" を"#{output}" にして式展開すると入力した文字になりますが
#{} をしなくて入力した文字にすることはどうすればよいのでしょうか?
#{}だと面倒なのですが・・
0086デフォルトの名無しさん2006/11/25(土) 18:44:15
>>85
"output" のクォートを取ってみな
0087デフォルトの名無しさん2006/11/25(土) 23:42:37
>78
その三者で言えば OS。 shebang 行の解釈はシステムコールがやる。どっちみち77が正しい。
0088デフォルトの名無しさん2006/11/26(日) 17:07:36
>>79
そりゃexitしたらそれ以上実行されんわな。
0089デフォルトの名無しさん2006/11/26(日) 17:20:09
subから何も返してないし。

module 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:06
どうせRubyスクリプト書いたことないんだろうな、と思う
0091デフォルトの名無しさん2006/11/26(日) 18:58:38
その気持ちはわからんでもない

Rubyスクリプトをある程度書けるようになった人で
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:39
1. gsub を4つ繋げる
2. 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:55
out = "ARAFAFAFAFFFAFATRWTATQWTWQTRQWTQTQTQTQTQWTQWEFTQWETQWTQWTTAFAFAFRATRARTA"

start = 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
>>94
> 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
>>95
というか、前者の書き方が見にくいからこその#{}だよな。
0097デフォルトの名無しさん2006/11/26(日) 22:03:34
>>95
ありがとうございます!無事できました。
#{}を式展開とだけ覚えていたのですが、文字列中で有効なんですね。勉強になりました。
0098デフォルトの名無しさん2006/11/26(日) 22:04:36
なんか気持ち悪いな

j = start.to_i - 150 + i
moji << "#{out[i,3]}(#{j}),"

埋め込むのは変数やメソッドだけにしてこう書こうぜ
0099デフォルトの名無しさん2006/11/26(日) 22:53:57
俺は#{}なんて滅多に使わないな
括弧やクォートの囲みは浅くしたい
0100992006/11/26(日) 22:56:11
+ を多用するようなら sprintf してる
0101デフォルトの名無しさん2006/11/26(日) 23:58:59
質問。

make_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
>>101
俺は上が好み。
0103デフォルトの名無しさん2006/11/27(月) 00:44:54
>>101
後者はretryの取り扱いミスが怖いので前者
確かにディスクアクセスが余分で気持ち悪いけどね

本当は後者がウツクシイんだろうな、と思う
0104デフォルトの名無しさん2006/11/27(月) 00:51:22
db=PStore.new(file)で存在しないファイルを指定してもdb['hoge']がnilを返すので
泣いたことを思い出した
0105デフォルトの名無しさん2006/11/27(月) 10:03:46
文字列の最後の1文字や2文字を消すにはどのメソッドを使えばよいのでしょうか?
0106デフォルトの名無しさん2006/11/27(月) 10:28:05
sum_string.slice!(-1, 1)とかslice!(-1, 2)とか
0107デフォルトの名無しさん2006/11/27(月) 10:50:54
>>106

(-1, 2) で試したところ、(-1, 1) と同じ結果がでてきたのですが・・・
0108デフォルトの名無しさん2006/11/27(月) 11:44:03
>>105
普通、Rubyでは一発ではできない。
Rubyの文字列枚挙操作は、1バイトを単位として動作し、日本語2バイト文字列を「1文字」として解釈しない。

が、1バイトの英数字だけならStringのsliceメソッドが使える。
>>106はよくある間違い(というかこれ仕様が意地悪)なので注意。
0109デフォルトの名無しさん2006/11/27(月) 11:46:36
>>107
う。すまんボケてた。
後ろ二文字ならslice!(-2, 2)とか、
めんどくさけりゃstr.slice!(-2, str.length)だな。
というかリファレンスのString#slice!を参照
0110デフォルトの名無しさん2006/11/27(月) 11:48:36
>>108
仕様で最後のslice(-1, 1) でしか無理ってことかな。
0111デフォルトの名無しさん2006/11/27(月) 11:50:08
>>105
$KCODEをきちんと指定+実行コスト度外視だったら、
arr = str.split(//)
arr.pop
str = arr.join
とか。
0112デフォルトの名無しさん2006/11/27(月) 11:57:28
>>108-109
ありがとうございました。無事できました。
日本語でも一発でできるようなメソッド装備すればいいのに。
0113デフォルトの名無しさん2006/11/27(月) 11:58:15
>>110
Rubyの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
>>114
そのwordを何で保持してるかに拠るだろ。
Arrayならreverseすればいいし。
0116デフォルトの名無しさん2006/11/27(月) 16:10:51
# self[nth, len]=val
str[0,0] = prefix
# self[regexp]=val
str[/^/] = prefix
# sub!(pattern, replace)
str.sub!(/^/, prefix)
0117デフォルトの名無しさん2006/11/27(月) 16:48:04
>>104
db.root?('hoge')を使うしか。
db['hoge']すると例外が発生してほしいってこと?
0118デフォルトの名無しさん2006/11/27(月) 17:48:53
「トランザクションの対象のファイルを読み込めません」という例外が欲しいんだろう

irb> h=Hash.new
irb> p h['hoge']
nil

これにあわせた動作なんだろうけどな
0119デフォルトの名無しさん2006/11/27(月) 19:35:52
すみません。rubyからshellを使用する場合についてお聞きしたい
ことがあります。
環境: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:02
>>119
system("program1")
system("gnuplot script1")

とか

`program1`
`gnuplot script1`

じゃダメですか?
0121デフォルトの名無しさん2006/11/27(月) 20:41:05
ファイルから読み込む時、そのファイルの最後の行だけ読み込むにはどうすればいいでしょうか。
大きなファイルを扱うのですが、最後の行だけ欲しいのです。

後ろから100バイト読んで、改行コードが無かったらまた100バイト読む。
という感じで出来るかな?と思ったのですが、
「後ろから読み込む」やり方がわからないです。
0122デフォルトの名無しさん2006/11/27(月) 21:10:25
line = IO.readlines(filename)[-1]
0123デフォルトの名無しさん2006/11/27(月) 21:15:37
>>122
大きなファイル扱うってかいてるじゃんか。
File#seekで読み込み位置ずらしていくのがベストじゃないの?
0124デフォルトの名無しさん2006/11/27(月) 21:17:55
>>121
IO#seek(offset, IO::SEEK_END)
あたりが使えそう…だろうか。
まぁ、めんどいことになるのは確かだ。
01251212006/11/27(月) 21:26:39
>>122-124
なるほど・・・
かなり面倒な事になりそうなんですね。
とりあえず>>124を参考にしてやってみます。
0126デフォルトの名無しさん2006/11/27(月) 22:51:01
>>125
レシピブックにそういう話が載ってたような気がする
01271212006/11/27(月) 23:45:06
>>126
レシピブック、今手持ちに無いので明日見てみようと思います。

それともう一つ問題が。
無限ループしてる訳では無いのですが、巨大なファイルを扱っているので
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
>>127
普通の手法で書いてる限り巨大なファイルとスタックオーバーフローは全くなんの関係もない。
Rubyがstack level too deepと言うのは、Rubyがバグってないかぎりは関数呼び出しの階層が深すぎる場合だけ。
噛み砕いて言うと、関数から関数を呼び出してその関数から関数を呼び出して、ってのを数千回繰り返すと起きる。
つまり自分が書いてるコードが悪いだけだ。

プログラムをよく眺めて考えろ。頭の中で実行してみろ。マニュアルを読め。
ところどころでpして結果を確かめろ。思い込みでコードを書くな。
あと思い込みで質問するな。
01291192006/11/28(火) 01:36:42
>>120
レスありがとうございます。
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:40
>>129
system()で呼び出されるシェル環境は呼び出される都度
別のサブプロセスになるんじゃなかったけか。
#だから2番目のsystem()でカレントディレクトリを変更しても
# 3番目以降のsystem()にはその影響が及ばない。
system("mkdir under; cd under; program1; gnuplot script1")
としてみたらどうよ。
いやおれはRubyは知らないんだけどね。
手元の環境では上のようにして動いたぞ。
0131デフォルトの名無しさん2006/11/28(火) 02:09:15
>>129
system の中身はシェルなんだから chdir じゃなくて cd。
cd 自体の返り値を使うわけじゃないんだからバッククォートじゃダメ。

system("mkdir under; cd under; program1; gnuplot script1")
0132デフォルトの名無しさん2006/11/28(火) 02:10:55
あ、かぶった。
0133デフォルトの名無しさん2006/11/28(火) 02:18:03
>>129
どうせプログラムの構造について考えないなら黙ってshでやりゃすぐじゃね?
覚えてて損はないし、生きてるうちは廃れないだろ。
0134デフォルトの名無しさん2006/11/28(火) 03:01:14
Rubyで1日悩むものもシェルスクリプトで割り切って作ると1時間くらいでできたりするよな
Rubyとのインターフェースもファイル作ってパイプとかリダイレクトとかで済んだりする
01351272006/11/28(火) 04:59:41
>>128
質問の仕方が悪かったですね。ごめんなさい。
ある研究で、巨大なファイルに10万程度の要素があって、その要素を繋げていくプログラムを作っています。
要素を繋げる為にいくつかの関数を用意してるのですが、関数を1000回程度呼び出した所でstack level too deep
になります。
が、こちらとしては正常な動作なので、もっと要素を繋いで行って欲しい。という訳なんです。

Linuxで動かしてみたら2000回程度呼び出したところでメモリ(2G)から溢れてスワップするようになったので、
仰るとおりプログラムを見直してみようと思います。
Windowsでは、stack level too deepを回避する手段は無さそうですね。
0136デフォルトの名無しさん2006/11/28(火) 06:24:31
呼び出しが再帰になってるんじゃないの?
再帰を非再帰の繰り返しに変更してみな
01371192006/11/28(火) 09:43:00
>>130,131

レスありがとうございました。教えて頂いた方法で解決しました。
解説をして頂いて、どこが問題なのか理解できました。

fork()は、サブプロセスが立ち上がることは知っていたんですが、
system()がサブプロセスになることを知りませんでした。

>>133,134
確かに、最初からshellでやった方が楽だったような気がします。
Rubyで行う処理もあり、shellをRubyから呼び出した方が手っ取
り早いかなぁと最初は思っていたので。

この度は、お手数をお掛けしました。m(_ _)m

0138デフォルトの名無しさん2006/11/28(火) 11:47:14
mkdir程度なら
require 'fileutils'というのもあるがな。
0139デフォルトの名無しさん2006/11/28(火) 11:54:22
おお、mkdir_p があるのか。
0140デフォルトの名無しさん2006/11/28(火) 18:02:27
>>135
再度書くがスタックオーバーフローが起こるのは自分の責任。
そもそもスタックがあふれるようなコードを書くべきでないだけの話。
正常な動作というのも勝手な思い込み。
WindowsもLinuxもその他色々もスタックは有限。
書き方が悪ければいずれにせよいつか起こる。
起こるまでの時間が短いか長いかの違いがあるだけ。
0141デフォルトの名無しさん2006/11/28(火) 18:10:24
winではpython使えってことだな
0142デフォルトの名無しさん2006/11/28(火) 18:11:46
再帰関数でつないでいってるのかな。
0143デフォルトの名無しさん2006/11/28(火) 18:29:17
Rubyは8000行ぐらい以上読ませたりすると
行番号がループする
って話をどっかで聞いた。RHGだっけ。
0144デフォルトの名無しさん2006/11/28(火) 18:37:08
[ruby-dev:29569]に、
Windowsなプラットフォームで、実際に使えるスタックを十分使わな
いうちにstack level too deepになってしまうという問題が…(略)

って話が。
0145デフォルトの名無しさん2006/11/28(火) 19:13:23
カモン186
0146デフォルトの名無しさん2006/11/28(火) 19:27:06
>>144
それは本質ではない。
安直にスタック食い潰して死亡するコードはイクナイという話。
0147デフォルトの名無しさん2006/11/28(火) 21:12:05
50万行程のファイルがるのですが、そのうちの5万行を読み込んで作業する
プログラムを作成しています。


流れとしましては、
50万行ファイルオープン
↓
指定された5万行を配列に格納。
↓
ファイルクローズ

を考えているのですが、配列に5万行を入れて作業するのと
5万行に分割したファイルを読み込むのとではどちらが軽く処理できるのでしょうか?

しょうもない質問ですが宜しくお願いします。
0148デフォルトの名無しさん2006/11/28(火) 21:14:19
>>147
しょうもないと思うなら自分で両方実装してベンチとれや
0149デフォルトの名無しさん2006/11/28(火) 22:04:28
スタックの残りを意識しないといけないプログラミングを強要するプログラム言語はゴミ

とか言ってみる
0150デフォルトの名無しさん2006/11/28(火) 22:41:52
スタックの残りを意識しなくても書けるプログラミング言語って、たとえばなに?
0151デフォルトの名無しさん2006/11/28(火) 22:50:40
チューリングマシン?
0152デフォルトの名無しさん2006/11/28(火) 22:58:03
こういうプログラムを書くとスタックが足りなくなるので注意しましょう

というような解説はあってもいいな
0153デフォルトの名無しさん2006/11/28(火) 23:41:05
>>152
再帰。
0154デフォルトの名無しさん2006/11/28(火) 23:49:51
>>152
入門書では見たことないな
その辺のフォローはあってもいいよね
0155デフォルトの名無しさん2006/11/29(水) 01:30:45
チューリングマシンはプログラミング言語ではありません
■ このスレッドは過去ログ倉庫に格納されています