Ruby 初心者スレッド Part 23
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
2008/11/20(木) 04:30:21【Ruby1.9 は不安定な開発版であり初心者には全く向きません】
【最新安定版の Ruby1.8.7 の使用をお勧めします】
※1.8.7 は1.8 と 1.9 の橋渡しをするためのリリースです。
1.9 の新機能の一部が利用可能なので初学者にお勧めです。
※ただし十分安定しているとは言えないので
プロダクション環境での利用にはお勧めしません。
関連スレやURLは>>2-8あたりを見てください。Ruby on Railsの質問はRailsスレへ。
■質問する人へ
質問する前に次の3つをすること。ここで回答を待つよりそのほうが早い。
・モジュール名やエラーメッセージでググる
・マニュアルで引っかかったクラスの記述を探す http://www.ruby-lang.org/ja/man/
・FAQを一応読む http://www.ruby-lang.org/ja/man/?cmd=view;name=Ruby+FAQ
質問には以下を書くこと。へたくそな質問は再提出を要求される。
・詳しい内容(「動きません」「うまくできません」では回答しようがない)
・エラーメッセージ(自力で訳さずなるべくそのままで)
・実行環境(OS名、Rubyのバージョン(ruby -v でわかる))
・最終的にやりたいこと(もっとよい方法がある場合が多いので)
回答してくれた人には「ありがとう」のひとことをいってあげて。
■回答する人へ
相手は初心者、根気よく育てるつもりで。質問がへたくそなのも大目にみてあげる。
それができないならこないこと(だって初心者スレだもん)。
・既出な質問やFAQは「XXXを読め」でいいので、叩かない&怖がらせない。
・わけわかな質問にもエスパー発揮で。できれば質問の仕方を教えるぐらいで。
・自信がない回答ならその旨表明すること。誤った回答は初心者じゃ見抜けない。
0133デフォルトの名無しさん
2008/12/01(月) 21:50:27>1行目は捕捉しても意味がないエラー(エラーが出たこと自体がまずいとき)
うそつけ。
raise "message" は単にエラークラスを省略しただけであり、「捕捉しても意味がない」なんてことはない。
>2行目は捕捉して回復処理を行えうる例外
>3行目は捕捉可能でユーザーにも情報を与えたいとき
逆だろ。
ユーザに情報を与えるなら raise XxxError じゃなくて raise XxxError.new("message") のほう。
初心者スレでこんなウソを垂れ流さんでくれ。初心者が間違って覚えてしまうだろうが。
それともなんかの工作員か?
0134デフォルトの名無しさん
2008/12/01(月) 21:59:28>rescueでも例外クラスを省略するとRuntimeError以下を捕捉する。
ウソつけ。
rescue =< ex
で捕捉されるのはStandardErrorだ。
>捕捉するな、ヤバいことになったぞ、ってときはExceptionとかRuntimeErrorよりスーパークラスな
>もの挙げたほうがいいと思う。
ひどい日本語だな。「ExceptionやRuntimeErrorより...」と読み間違えてしまうじゃないか。
「捕捉するな、ヤバいことになったぞ、ってときは、Exceptionのような
StandardErrorよりスーパークラスなものをあげたほうがいいと思う。」
「捕捉するな、ヤバいことになったぞ、ってときは、StandardErrorより上位の例外クラスを使ったほうがいいと思う。」
自分の日本語力のなさを「2chだからどうこう」と言い訳すんなよ?
0135デフォルトの名無しさん
2008/12/01(月) 22:15:390136デフォルトの名無しさん
2008/12/01(月) 22:55:540137132
2008/12/02(火) 01:54:41>rescue =< ex
>で捕捉されるのはStandardErrorだ。
フォローthx、ふつーに間違えた。
でもrescue => ex だと思う。肩の力抜けよ。
>ひどい日本語だな。「ExceptionやRuntimeErrorより...」と読み間違えてしまうじゃないか。
いいじゃん、Exceptionより上の例外クラスないし。
0138デフォルトの名無しさん
2008/12/02(火) 02:18:02rescue Exception => ex とか書く奴が絶対出てくると思うんだが
0139デフォルトの名無しさん
2008/12/02(火) 02:27:28Rubyスクリプトからfatal触れないし。
JavaでError(だっけ?)系統の例外を捕捉するのがいい顔されないみたいに、やったら叱るしか
ないんじゃないのかなぁ…
irbみたいなのを書けるように、そう書けること自体は多分必要だし。
0140デフォルトの名無しさん
2008/12/02(火) 06:04:02その人にとってRubyは神聖なものでRubyしか取り柄がないのですよ
だから普通の指摘ができない
0141デフォルトの名無しさん
2008/12/02(火) 11:16:080142デフォルトの名無しさん
2008/12/02(火) 11:22:58間違ったことをしたり顔で書いてる人にいわれてもなあ・・・
0143デフォルトの名無しさん
2008/12/02(火) 11:24:47>けどライブラリのバグとかを教えるのにException挙げるぐらいしか手がないんだもんよん。
どういう意味?
0144デフォルトの名無しさん
2008/12/02(火) 11:39:19MLでも時々見る
記名でできるのはある意味凄いが真似したいとも思わん
0145デフォルトの名無しさん
2008/12/02(火) 15:54:47Cではassertマクロを使うような場所というか…
case value
when :hoge
...
when :piyo
...
when :foo
...
else
#絶対に来ないはずの分岐
raise Exception, 'must not happen'
end
みたいな。るびまで読んで使い出した。
0146デフォルトの名無しさん
2008/12/02(火) 16:35:17get_elementsで要素ごとに引っ張り出すようにしたら
その数が20個くらいに膨れ上がりました。
その処理が終わるまでものすごく遅くなる(終了まで10秒程度)ですが、
何か高速に行なう方法とかないですか?
通常要素ね具体的には特定のタグ名ごとに特定の変数に入れる処理を一番高速にやるにはどのようにするのが一番いいでしょうか。
0147デフォルトの名無しさん
2008/12/02(火) 16:45:40REXML は「全部 Ruby で書かれてる! Ruby 最高!」という人が使うライブラリ
遅いなと思ったら(そしてプログラムのインストールが可能な環境なら)即っと乗り換えてよし
0148デフォルトの名無しさん
2008/12/02(火) 17:12:48in seconds libxml rexml
opening 0.003954 0.104750
attribute_add 0.001895 0.011114
subelems 0.000585 0.004729
xpath 0.013269 2.981499
0149デフォルトの名無しさん
2008/12/02(火) 20:11:30無料のレンサバってインストールできるでしょうか?
0150デフォルトの名無しさん
2008/12/02(火) 20:22:07>>149
そのレンタルサーバサービスでrubygemsのユーザーインストール実績があればたぶん可能
まあ、つまり、無料レンタルサーバではきっと無理だろうな
俺はRubyスクリプトを外部使用するためだけにさくらインターネットの年5千円プラン使ってる
0151デフォルトの名無しさん
2008/12/02(火) 20:29:02Ruby以外の外部プログラムにぶん投げて結果を置換してevalしたほうが速いとかマジキチ
0152デフォルトの名無しさん
2008/12/02(火) 20:42:06SAXライクなAPIがあったと思うので挑戦してみては
REXML SAX でぐぐったらそれなりに引っかかるようだ
0153デフォルトの名無しさん
2008/12/02(火) 22:21:20eval(<<EOS)
def hello(person)
eval "Hello, #{person}!"
end
EOS
これはエラーになるよね
> NameError: undefined local variable or method `person' for main:Object
0154デフォルトの名無しさん
2008/12/02(火) 22:41:36eval(<<EOS)
def hello(person)
"Hello, \#{person}!"
end
EOS
0155デフォルトの名無しさん
2008/12/02(火) 22:45:27そもそも2重evalで何がやりたいのかを詳しく
そのサンプルコードでは、意図がよく分からない
0156デフォルトの名無しさん
2008/12/02(火) 23:03:12def hello(person)
return eval("Hello, #{person}")
end
という。eval文の入ったメソッド定義そのものをeval文で書きたいのだろ
0157デフォルトの名無しさん
2008/12/02(火) 23:05:29つまり文字列全体をダブルクオートでくくったのと同じ状態になるので、展開が起きる
外側のevalに渡された文字列を評価する時点で#{person}が展開されちゃって、変なことになってる
展開を抑制するのが楽な回避法。'EOS'とすべし
helloメソッドは文字列を返したいのかもしれないけど、
それだと内側のevalにも括弧が足りない
eval <<'EOS'
def hello(person)
eval %q[ "Hello, #{person}!" ]
end
EOS
print hello("Ruby") # => Hello, Ruby!
0158デフォルトの名無しさん
2008/12/02(火) 23:08:58変数展開がないならメソッド定義をevalで書く必要なくね?
0159デフォルトの名無しさん
2008/12/02(火) 23:41:34それっぽいのがここしかないけど
http://webos-goodies.jp/archives/51357031.html
他にないですか?
やりたいのはsshで他サーバーに接続して、suでパスワードを入力し、
grep + パラメータを実行しその結果をブラウザに出力したいです
初めてrubyを使って無謀なことをしてる気もしますが、標準出力はどうにかなりましたが、
入力がどうもうまくいかず
net/sshのリファレンスページもみましたがいったいどこを探せばメソッド載ってるのかわからない
です
0160デフォルトの名無しさん
2008/12/03(水) 20:05:45http://net-ssh.rubyforge.org/ssh/v1/chapter-5.html
http://rubyforge.org/forum/message.php?msg_id=32802
0161デフォルトの名無しさん
2008/12/03(水) 22:56:25うおおありがとう!まさに求めていた物だ!
0162デフォルトの名無しさん
2008/12/04(木) 07:14:050163デフォルトの名無しさん
2008/12/04(木) 07:21:24その質問には、熟慮の末に「ない」と答えるのが妥当な気がする
0164デフォルトの名無しさん
2008/12/04(木) 07:25:21ということは、あるにはあるけど使えないとか、そんな感じですか?
0165デフォルトの名無しさん
2008/12/04(木) 07:25:57素直にPHPかPerlの使っとけ
0166デフォルトの名無しさん
2008/12/04(木) 08:37:00一応名前だけでも教えてください。
0167デフォルトの名無しさん
2008/12/04(木) 09:48:40tDiary、Pinky:blog、lily
もしかして普通に名前挙げた俺、空気読めてない?
0168デフォルトの名無しさん
2008/12/04(木) 10:00:59Rubyをやりたいんじゃなくてブログシステムが欲しいんだろうし
0169デフォルトの名無しさん
2008/12/04(木) 10:16:04日本における Perl の隆盛は Perl でカウンタと掲示板が作られたことだからな
「なんかごっつい Rails だけじゃない Ruby」を推進するなら今しかない
0170デフォルトの名無しさん
2008/12/04(木) 10:52:08はい。
['hello', 'goodbye'].each do |greeting|
eval(EOS)
def #{greeting}(person)
eval "#{greeting.capitalize}, #{person}!"
end
EOS
end
実際はこんな感じです。展開抑制されると思わなかったので…
0171デフォルトの名無しさん
2008/12/04(木) 18:56:49トップレベルにメソッドを定義するため?
0172デフォルトの名無しさん
2008/12/04(木) 21:28:23ふつーはこう書く
['hello', 'goodbye'].each do |greeting|
eval(<<-EOS)
def #{greeting}(person)
'#{greeting.capitalize} %s!'%person
end
EOS
end
0173デフォルトの名無しさん
2008/12/05(金) 12:24:58【ちゃんと動くプログラム】
if 90<=tokuten ; foo[9] += 1 ; end
if 80<=tokuten && tokuten<90 ; foo[8] += 1 ; end
if 70<=tokuten && tokuten<80 ; foo[7] += 1 ; end
if 60<=tokuten && tokuten<70 ; foo[6] += 1 ; end
if 50<=tokuten && tokuten<60 ; foo[5] += 1 ; end
if 40<=tokuten && tokuten<50 ; foo[4] += 1 ; end
if 30<=tokuten && tokuten<40 ; foo[3] += 1 ; end
if 20<=tokuten && tokuten<30 ; foo[2] += 1 ; end
if 10<=tokuten && tokuten<20 ; foo[1] += 1 ; end
if 0<=tokuten && tokuten<10 ; foo[0] += 1 ; end
【上記では長いのでイテレータで短くしたプログラム(正しく動かない)】
(1..8).each do |i|
if (90<=tokuten && tokuten<=100) ; foo[9] += 1 ; end
if (i*10)<=tokuten && tokuten<(i+1)*10 ; foo[i] += 1 ; end
if 0<=tokuten && tokuten<10 ; foo[0] += 1 ; end
end
配列はちゃんと0で初期化してあります。
短くしたプログラムはfoo[9]以外はちゃんと動いてるみたいです。
foo[9]だけが明らかにおかしい人数になるので不思議です・・・
なんとなくかっこで囲んでみたけどダメでした。もちろん上記と同じように「90<=tokuten」も試しましたがダメでした。
助言お願いします。
0174デフォルトの名無しさん
2008/12/05(金) 12:42:43それか1..8を0..9にして、10点未満も90点以上もiの一般式に組み込むかのどっちか
0175デフォルトの名無しさん
2008/12/05(金) 12:44:23頭が痛くならない解決法のひとつは、case文を使うこと
case tokuten
when 90..100 then foo[9] += 1
when 80..89 then foo[8] += 1
when 70..79 then foo[7] += 1
# 中略
when 10..19 then foo[1] += 1
when 0..9 then foo[0] += 1
end
もうひとつは、得点とカウンターの関係を冷静に見て条件を抽出すること。
「得点の 1 の位に等しい配列要素を +1 する」
「ただし、100 点の場合は 9 要素目を +1 する」
「なお、9 を 10で割ると 9 /10 = 0 である」
if tokuten == 100 then
foo[9] += 1
else
n = tokuten / 10
foo[n] +=1
end
0176デフォルトの名無しさん
2008/12/05(金) 12:55:13>うおー、初心者スレっぽいぞ
たしかにな
>「得点の 1 の位に等しい配列要素を +1 する」
10の位の間違いか?
>「ただし、100 点の場合は 9 要素目を +1 する」
これはひっかかりそうだなー
コードはもうちょっと簡潔になるな。
n = tokuten == 100 ? 9 : tokuten / 10
foo[n] += 1
または
if tokuten == 100
n = 9
else
n = tokuten / 10 # ex. 85 -> 8, 31 -> 3
end
foo[n] += 1
0177デフォルトの名無しさん
2008/12/05(金) 13:27:46こういう条件にするとそう処理する理由がそれほど明らかでない。
条件は上界により与えられるとして考える方がよくないか。
いつぞやRubyスレで話題になった Range#bound があれば
idx = (0..9).bound(tokuten / 10)
foo[idx] += 1
0178デフォルトの名無しさん
2008/12/05(金) 13:38:100179デフォルトの名無しさん
2008/12/05(金) 13:40:50100 点に関しては集計なり統計なりするときの処理に扱いを委ねるべきで、
データの時点で組み込んでしまうべきではない
0180デフォルトの名無しさん
2008/12/05(金) 13:55:20>>174 も書いてるがその「正しくないコード」の意味するところは、
i を 1 から 8 に変更しつつ do 〜 end の中のコードを実行するという事だ。
foo[9] 以外は動いているって言ってるけど foo[0] にも同じ問題がある。
「do 〜 end 中の文は tokuten の値が何であろうと 8回実行されてる」
という事を頭に入れてもう一度コードをよくみて考えてみて。
多分上手く動いていると思っている部分も、あまりよくないと気付くだろう。
0181デフォルトの名無しさん
2008/12/05(金) 13:58:12時々混乱したことはあった
0182173
2008/12/05(金) 14:17:41その通りですね。脳内で考えたときは一度条件に当てはまったら勝手にeach文から抜けてました・・・
>>175
case文だと元のfor文と対して長さが変わらないですねw
もう一つの案、とても参考になりました。ありがとうございます。
>>176
条件演算子、思いもつかなかった方法です。
短くて使いやすそうです。ありがとうございます。
>>177
む・・難しい・・・
コピペしても動かなかったので何か読み込ませるものなんですね。
レスくれたみなさま、ありがとうございました。
得点を割ってそのままインデックスとして使う方法は私にとっては斬新で勉強になりました。
重ね重ね、ありがとうございました。
0183デフォルトの名無しさん
2008/12/05(金) 18:26:56なあ、初心者にちょっと聞いてみたいんだけど、条件演算子って難しい?
n = tokuten == 100 ? 9 : tokuten / 10
とか理解できる?
世の中には条件演算子を禁止するようなプロジェクトがあって、頭おかしいと思ってるんだけど、
初心者にとっては条件演算子がほんとうに難しいのかどうか気になる。
0184デフォルトの名無しさん
2008/12/05(金) 18:30:16乱用されてソースコードが酷いことになるのを防ぐためじゃない?
0185rubyの初心者
2008/12/05(金) 18:34:240186デフォルトの名無しさん
2008/12/05(金) 18:44:57おまえ、rubyの初心者じゃなくてPython上級者だろ。
0187デフォルトの名無しさん
2008/12/05(金) 18:50:36難しいという理由からなら、こんなに一般的に禁止が広まるわけがない
0188デフォルトの名無しさん
2008/12/05(金) 18:55:02sym = n.zero? ? :hoge : :fuga
とかやられるとわけがわからない。
sym = if n.zero? then :hoge else :fuga end
ほらわかりやすい。
0189デフォルトの名無しさん
2008/12/05(金) 18:56:290190デフォルトの名無しさん
2008/12/05(金) 18:57:55変なとこで改行してカッコつけてネストする奴が出てくるのが嫌われてる理由の一つだと思う
そんなに複雑なら if 文で書くかリファクタリングしろ
0191デフォルトの名無しさん
2008/12/05(金) 19:02:21もっと2〜3文字のキーワードで区分けされていると読み落としがないんだが
0192デフォルトの名無しさん
2008/12/05(金) 19:05:210193デフォルトの名無しさん
2008/12/05(金) 19:18:320194デフォルトの名無しさん
2008/12/05(金) 19:28:41>sym = n.zero? ? :hoge : :fuga
>とかやられるとわけがわからない。
そうか、初心者はこの程度でもわけがわからなくなるのか。
>sym = if n.zero? then :hoge else :fuga end
>ほらわかりやすい。
どこがだよ。
0195デフォルトの名無しさん
2008/12/05(金) 19:45:21条件演算子で短くまとめた条件分岐はほぼ100パーセントの確率で
のちのち長い if 文に書き換える羽目になるというのがどうにも
嫌われる人はここで条件演算子使用を強行する
0196デフォルトの名無しさん
2008/12/05(金) 20:00:260197デフォルトの名無しさん
2008/12/05(金) 20:22:43ifの返す値を使うプログラムは読みにくい
0198デフォルトの名無しさん
2008/12/05(金) 21:21:19[1, 2, 3].send("[](1)") が 2 を返すような
0199デフォルトの名無しさん
2008/12/05(金) 21:23:200200173
2008/12/05(金) 21:26:57条件演算子が難しいなんて書いてませんよ・・・私・・・
n = tokuten == 100 ? 9 : tokuten / 10
「tokuten」が100ならば「9」を「n」に代入、elseなら「tokuten/10」を「n」に代入ですよね
0201デフォルトの名無しさん
2008/12/05(金) 21:32:06うおー引数2個ーめんどー
ありがとうございます
0202デフォルトの名無しさん
2008/12/05(金) 22:12:43アー、悪い、
>条件演算子、思いもつかなかった方法です。
って書いてあるから、初心者には理解するのが難しいのかと思った。
わかってるならすまんかった。気を悪くせんでくれ。
0203デフォルトの名無しさん
2008/12/06(土) 01:23:580204デフォルトの名無しさん
2008/12/06(土) 01:29:540205デフォルトの名無しさん
2008/12/06(土) 01:40:02メソッド呼び出しているだけの行で
[BUG] Segmentation faultってバグ落ちしたメッセージが表示されるですけど、
これってどこでバグっているのか原因わかりますか?
後、ルビーのバグ回避のプログラミングの仕方ってあるでしょうか?
ルビーの落とし穴というページ見ても今一バグが発生する原因や回避の方法が分からないもので。
0206デフォルトの名無しさん
2008/12/06(土) 01:42:36ルビーのバージョンは1.8.6で無料サーバでつかうため、パッチやバージョンアップ以外の方法でバグ回避方法をおしえてください。
0207デフォルトの名無しさん
2008/12/06(土) 01:44:160208デフォルトの名無しさん
2008/12/06(土) 01:44:39ruby本体のbugだから、まずは最新版で試してみて。
それでも再発するなら、出来る限り余分な部分を削った再現コードを作って
ここか本スレかruby-listに晒せばおk。そのときruby -vの提示を忘れずに。
あとは偉い人がよろしくやってくれるはず。
0209デフォルトの名無しさん
2008/12/06(土) 01:47:13・・・まあ再現コード見せて。
そのコードを作ること自体が「回避の方法」だったりするし。
0210デフォルトの名無しさん
2008/12/06(土) 01:58:16openでファイル作成やREXML::Documentとグローバル配列とメソッドだけでね。
今やったらなぜメソッド中の注釈「# DATAURL 」の行を指して
[BUG] Segmentation fault
ruby 1.8.6 (2008-08-11) [i386-mswin32]
って出ました。わけわからん。
0211デフォルトの名無しさん
2008/12/06(土) 02:00:280212デフォルトの名無しさん
2008/12/06(土) 02:05:23RDEでデバッグしながらですがけど...
鯖だとデバッグできないですから..
0213デフォルトの名無しさん
2008/12/06(土) 02:18:57再現コードがないと、なんともコメントできない。
0214デフォルトの名無しさん
2008/12/06(土) 02:19:250215デフォルトの名無しさん
2008/12/06(土) 02:19:340216デフォルトの名無しさん
2008/12/06(土) 02:52:30Segmentation faultだけでは、アドバイスする側にもわけわからん
0217デフォルトの名無しさん
2008/12/06(土) 02:53:36何かが分かる気はしないけどね。
0218デフォルトの名無しさん
2008/12/06(土) 08:57:37それ以上のことはなんもならん
0219デフォルトの名無しさん
2008/12/06(土) 10:53:07再現コード無いのは無理だなあ
0220デフォルトの名無しさん
2008/12/06(土) 14:02:120221デフォルトの名無しさん
2008/12/06(土) 14:11:450は成功、1かそれ以上は失敗
ということで、ただの例ですな
0222デフォルトの名無しさん
2008/12/06(土) 14:18:02exit(3)の3はmanのセクション番号でライブラリコールだってこと。
詳しくはman man
他にもwrite(2)とかがある
0223デフォルトの名無しさん
2008/12/06(土) 14:19:29多分それ違う
>220
exit(3) のリンク先を見れば判ると思うけど、この exit はC言語の関数の exit() のこと。
要はRubyが内部でやってる処理を説明している。
Linuxのマニュアルのセクション3にあるexit()の通りの処理をしてるよ、という意味。
0224デフォルトの名無しさん
2008/12/06(土) 15:51:10>>221-223
ありがとうございました。
0225デフォルトの名無しさん
2008/12/06(土) 16:25:24なんでだよ
Rubyってなんでもできる万能言語って聞いたんだが
0226デフォルトの名無しさん
2008/12/06(土) 16:30:20ではその人を責めてください
サンタクロースが実在しなかったからといってサンタ役のお父さんをバシバシ叩くのはやめてください
0227デフォルトの名無しさん
2008/12/06(土) 22:22:34ワロタw
0228デフォルトの名無しさん
2008/12/06(土) 23:51:21Rubyのプログラム上からエクセルに渡して動かす、みたいなことはできますか?
0229デフォルトの名無しさん
2008/12/07(日) 00:35:40呼び出す側の言語が何であろうと出来るんじゃない?
0230デフォルトの名無しさん
2008/12/07(日) 00:37:450231デフォルトの名無しさん
2008/12/07(日) 06:28:28puts とか getsがメソッドですよといわれたのは良いんですが
self.puts
とか、
100.to__s
とかはわかるのですが
gets.chompはなぜgetsの後ろにchompが付くんですか?
メソッドの前に付くのが普通だと思ってたので・・・
0232デフォルトの名無しさん
2008/12/07(日) 07:14:23self.gets.chomp
getsの結果に対してchompするということ
つーかgetsはレシーバ書かないほうが普通だと思うが…
■ このスレッドは過去ログ倉庫に格納されています