Ruby 初心者スレッド Part 40
レス数が950を超えています。1000を超えると書き込みができなくなります。
0001デフォルトの名無しさん
2010/12/11(土) 15:46:15★注意★ Ruby 1.9.2 は初心者には若干時期早尚です。初心者には Ruby 1.8.7 を強くお勧めします。
文字エンコーディング等の外部基礎知識が必要な上、不完全対応の第三者ライブラリでの問題の切り分けが手間です。
迷う点の少ない1.8.7に習熟→おもむろに1.9.2の変更点のみ重点学習、とすればスムーズに移行できるでしょう。
関連スレやURLは>>2-5あたりを見てください。Ruby on Rails の質問は Webプログラミング板の 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を読め」でいいので、叩かない&怖がらせない。
・わけわかな質問にもエスパー発揮で。できれば質問の仕方を教えるぐらいで。
・自信がない回答ならその旨表明すること。誤った回答は初心者じゃ見抜けない。
0893デフォルトの名無しさん
2011/02/06(日) 18:27:00319;C:\Windows\Microsoft.NET\Framework\v3.5;C:\Program.obj' を開くことができませ
ん。
ってなコンパイルエラーがでたので、該当箇所っぽいところを
--- DLDFLAGS = -link -incremental:no -debug -opt:ref -opt:icf -dll $(LIBPATH)
+++ DLDFLAGS = -link -incremental:no -debug -opt:ref -opt:icf -dll
--- EXT_DLDFLAGS = -link -incremental:no -debug -opt:ref -opt:icf -dll $(LIBPATH)
+++ EXT_DLDFLAGS = -link -incremental:no -debug -opt:ref -opt:icf -dll
としたのがだめだったのでしょうか。。。
>>892
せっかくCのeRuby実装があるのでパフォーマンスのためにも、使ってみたいのです
0894デフォルトの名無しさん
2011/02/06(日) 18:40:13LIBPATH = "C:/Program Files/Microsoft Visual Studio 10.0/VC/LIB/"
or
LIBPATH = "C:\Program Files\Microsoft Visual Studio 10.0\VC\LIB\"
or
LIBPATH = "C:\Program Files\Microsoft Visual Studio 10.0\VC\LIB"
DLDFLAGS = -link -incremental:no -debug -opt:ref -opt:icf -dll $(LIBPATH)
LDSHARED = cl -nologo -LD
EXT_DLDFLAGS = -link -incremental:no -debug -opt:ref -opt:icf -dll $(LIBPATH)
などと直しても、
LINK : fatal error LNK1181: 入力ファイル 'C:/Program Files/Microsoft Visual Stud
io 10.0/VC/LIB.obj' を開けません。
となります。
0895デフォルトの名無しさん
2011/02/06(日) 21:43:350896デフォルトの名無しさん
2011/02/06(日) 23:43:19devkitでコンパイルしたほうが早そう
0897デフォルトの名無しさん
2011/02/07(月) 00:22:57cで実装されたerubyは遅いのでお勧めしない。まだerbのほうがまし。
0898デフォルトの名無しさん
2011/02/07(月) 01:28:29>>897
ありがとう。
しかし
ERBでもerubyでもロードの度にCPUが100%になる。。。
0899デフォルトの名無しさん
2011/02/07(月) 02:13:34確か特定のバージョンのRubyは糞だったはず
0900デフォルトの名無しさん
2011/02/07(月) 02:55:511.8.7です。
0901デフォルトの名無しさん
2011/02/07(月) 08:28:14すでに書かれてるけど、erubyはCで書かれているのに遅いし、print文を使っていて柔軟性に欠けるので、やめたほうがいい。
>>897
erbはファイルをrubyコードに変換する部分が遅いので、erubisのload_fileを使ったほうがいい。
eruby = Erubis::Eruby.load_file('example.rhtml')
print eruby.run(binding)
0902デフォルトの名無しさん
2011/02/07(月) 08:46:31ttp://twitter.com/idesaku/status/2719421881
0903デフォルトの名無しさん
2011/02/07(月) 16:24:21fruits = [['banana', 3], ['cherry', 2], ['banana', 1], ['apple', 4], ['banana', 5]]
fruits.sort{|a, b| ??? }
欲しい結果
[["cherry", 2], ["banana", 3], ["banana", 1], ["banana", 5], ["apple", 4]]
0904デフォルトの名無しさん
2011/02/07(月) 16:34:320905デフォルトの名無しさん
2011/02/07(月) 17:10:30fruits.each.with_index.sort {|a,b|
(b[0][0] <=> a[0][0]).nonzero? || a[1] <=> b[1]
}.map(&:first)
とか。
もっとスマートに出来そうだけど。
単なる数値じゃなくオブジェクトの配列をソートすることが多いRubyなのに
0907デフォルトの名無しさん
2011/02/07(月) 17:32:38http://redmine.ruby-lang.org/issues/show/1089
0908デフォルトの名無しさん
2011/02/07(月) 18:02:48酷い脊髄反射レスだなこりゃ
0909デフォルトの名無しさん
2011/02/07(月) 18:18:04ありがとうございます。
期待通りの動作が得られました。
0910デフォルトの名無しさん
2011/02/07(月) 18:22:36こんなんとか?まだ分かり辛い気もする
0911デフォルトの名無しさん
2011/02/07(月) 18:30:020912デフォルトの名無しさん
2011/02/07(月) 18:31:29そいでマップしてソートしてリバースしてマップして(ry
みたいな気が狂ったようなコードを書いちゃう。
0913デフォルトの名無しさん
2011/02/07(月) 18:41:470914デフォルトの名無しさん
2011/02/07(月) 19:52:190915デフォルトの名無しさん
2011/02/07(月) 20:17:23Rubyではお手軽に書けるけど、他のLLだと「やりたくても、できない」からね
いわゆる「酸っぱい葡萄」かな?
0916デフォルトの名無しさん
2011/02/07(月) 22:00:240917デフォルトの名無しさん
2011/02/07(月) 22:17:42メソッドと記号の意味を追えば分かる
俺でも分かったんだから大丈夫
0918デフォルトの名無しさん
2011/02/07(月) 23:20:20# フルーツと添字をペアにして、配列arrに格納
arr = []
fruits.each_with_index {|x, i| arr << [x, i] }
# 比較方法を指定してソート
arr.sort! {|pair1, pair2|
# フルーツの名前で比較
val = pair2.first[0] <=> pair1.first[0]
# それが同じだった場合にのみ、添字で比較
val != 0 ? val : pair1.last <=> pair2.last
}
# フルーツだけを取り出す
p arr.collect {|pair| pair.first }
ここで、
arr = []
fruits.each_with_index {|x, i| arr << [x, i] }
が、905では
fruits.each.with_index
となっていて(これは1.9での書き方かな?)、
val = pair2.first[0] <=> pair1.first[0]
val != 0 ? val : pair1.last <=> pair2.last
が905では
(pair2.first[0] <=> pair1.first[0]).nonzero? || pair1.last <=> pair2.last
となっているわけだね。なるほど。nonzero?なんて初めて知った。
ttp://www.ruby-lang.org/ja/man/html/Numeric.html#nonzero.3f
0919デフォルトの名無しさん
2011/02/08(火) 00:10:12fruits.shuffle!
if fruits[0] >= fruits[1]
if fruits[1] >= fruits[2]
if fruits[2] >= fruits[3]
if fruits[3] >= fruits[4]
if fruits[4] >= fruits[5]
break
end
end
end
end
end
end
0920デフォルトの名無しさん
2011/02/08(火) 00:38:04array.shuffle! until array.each_cons(2).all? {|a,b| a < b }
# 1行ver.
0921デフォルトの名無しさん
2011/02/08(火) 00:46:37fruits.sort_by{|v| [v[0].bytes.map(&:-@),i+=1]}
0922デフォルトの名無しさん
2011/02/08(火) 01:35:11ワラタw
0923デフォルトの名無しさん
2011/02/08(火) 03:07:090924デフォルトの名無しさん
2011/02/08(火) 03:08:12それを言うなら無限の猿
無限の猿定理 - Wikipedia
http://ja.wikipedia.org/wiki/%E7%84%A1%E9%99%90%E3%81%AE%E7%8C%BF%E5%AE%9A%E7%90%86
0925デフォルトの名無しさん
2011/02/08(火) 06:32:590926デフォルトの名無しさん
2011/02/08(火) 06:44:02fruits.sort_by.with_index{|v,i| [v[0], i]}
Enumerator#with_indexの真骨頂
0927デフォルトの名無しさん
2011/02/08(火) 07:01:15降順じゃないじゃん
0928デフォルトの名無しさん
2011/02/08(火) 07:15:00なかったことに
fruits.sort_by.with_index{|v,i| [v[0], -i]}.reverse
0929デフォルトの名無しさん
2011/02/08(火) 07:27:480930デフォルトの名無しさん
2011/02/08(火) 08:01:120931デフォルトの名無しさん
2011/02/08(火) 08:19:47instance method Enumerable#sort_by
http://doc.ruby-lang.org/ja/1.9.2/method/Enumerable/i/sort_by.html
i = 0
fruits.reverse.sort_by {|v| [v[0], i += 1] }.reverse
0932デフォルトの名無しさん
2011/02/08(火) 08:26:30>>928みたいに、インデックスをマイナスにすれば、最初のreverseがいらないね。
俺も脊髄反射だw
i=0
fruits.sort_by {|v| [v[0], -(i += 1)] }.reverse
0933デフォルトの名無しさん
2011/02/08(火) 08:33:55連投すまそ。
i=0
fruits.sort_by {|v| [v[0], i -= 1] }.reverse
0934デフォルトの名無しさん
2011/02/08(火) 08:54:530935デフォルトの名無しさん
2011/02/08(火) 09:41:330936デフォルトの名無しさん
2011/02/08(火) 09:45:54これで思い出したけど円周率3.14...のなかにはどんな数字の組み合わせも入ってる可能性があるらしいね
例えば、人の名前を数字に当てはめてそこに生年月日とか生まれた時間とかくっつけたのを絶対見つけることができるらしい
それなら未来のこともどうにか数字にしてわかるんじゃね?って研究してる人の話を聞いたことがある
0937デフォルトの名無しさん
2011/02/08(火) 09:53:02「絶対見つけることが出来る」という結論は出ないと思う
円周率に0が100個続く列があるか、ってのは証明が難しいんじゃなかったか
0938デフォルトの名無しさん
2011/02/08(火) 09:54:07sort(:stable => true){|a| a<=>b }
sort(:method => :merge){|a| a<=>b }
0939デフォルトの名無しさん
2011/02/08(火) 10:07:16ごめんスレ違いなんだけど
その研究者が講演とかをやってそれを実演してるらしい
そこに用意してある円周率はたった数千〜万桁?ほどなんだけど
希望者の名前と生年月日の組み合わせは100%あるとのこと
0940デフォルトの名無しさん
2011/02/08(火) 10:08:21limit = 5
loop do |i|
break if i > limit
end
0941デフォルトの名無しさん
2011/02/08(火) 10:14:29limit = 5
i = -1
while true
i += 1
break if i >= limit
do_something
end
まあこれなら
i = -1
while (i += 1) < limit
do_something
end
だな
0942デフォルトの名無しさん
2011/02/08(火) 10:17:13名前をどういうふうに数字にしてるのかしらないけど、
単純に確率の問題。
0が100個だと、10の100乗ぶんの1の確率だから、10の100乗桁あれば、
あってもおかしくない。そんだけ。
0943デフォルトの名無しさん
2011/02/08(火) 10:31:18d
0944デフォルトの名無しさん
2011/02/08(火) 10:53:10リファレンスマニュアルにも書いてるけど、安定じゃないよ。
sort_by 使ってる例は i が肝。
0945デフォルトの名無しさん
2011/02/08(火) 10:56:39それ無限に見えないけど、こんな感じ?
5.times do |i|
end
0946デフォルトの名無しさん
2011/02/08(火) 11:07:02何回か話題になってた記憶がある
0947デフォルトの名無しさん
2011/02/08(火) 11:19:230948デフォルトの名無しさん
2011/02/08(火) 11:21:44そのときの結論はどうだったの?
ググったらこんな方法があったけど。
enum_for(:loop).with_index do |_, i|
break if i > limit
end
こんなんとかどうだろうか?
0.upto(Float::INFINITY) do |i|
break if i > limit
end
0949デフォルトの名無しさん
2011/02/08(火) 12:52:10元のloop置き換えちゃっていいじゃね理論
def loop
return unless block_given?
i = -1
yield i += 1 while true
end
loop{|i|
break unless i < 10
puts i
}
loop{
puts "#"; sleep(0.1);
}
0950デフォルトの名無しさん
2011/02/08(火) 15:17:21Enumeratorを外部イテレーターとしてまわすときにloopと組で使うわけです
counter = 5.times
loop do
p counter.next
end
while true
p counter.next #whileだと例外でエラー終了
end
0951デフォルトの名無しさん
2011/02/08(火) 15:23:160952デフォルトの名無しさん
2011/02/08(火) 15:52:38自分でStopIteration例外を補足する必要があります
カウンター付きloopの提案
引数つけたときだけカウンター回せばいいんじゃないだろうか
これなら既存の使い方のパフォーマンスも落ちないはず
ついでにEnumeratorも生成できれば便利なのでは
引数は succできるやつとEnumeratorのみ受け付けれられればいいかな
でも、名前がだめだめなのでまったく採用の見込みは無さそう
loopにはカウンターをまわすイメージが無いので
0953デフォルトの名無しさん
2011/02/08(火) 15:54:52def loop(counter = nil)
raise TypeError unless counter.nil? or counter.respond_to?(:succ) or Enumerator === counter
return enum_for(:loop,counter) unless block_given?
case
when counter.nil?
orig_loop{ yield }
when Enumerator === counter
orig_loop{ yield counter.next }
when counter.respond_to?(:succ)
orig_loop{ yield counter; counter = counter.succ }
end
end
limit = 5
i = 0
loop(1){|n| p n; break if (i+=1) >= limit}
i = 0
loop('a'){|n| p n; break if (i+=1) >= limit}
i = 0
loop((1..3).each.cycle){|n| p n; break if (i+=1) >= limit}
endless_counter = loop(0)
0954デフォルトの名無しさん
2011/02/08(火) 18:13:02loop.with_index{|_,i| p i }
とかできるんだなw初めて知った
0955デフォルトの名無しさん
2011/02/08(火) 18:49:36サーバ(CentOS5)のRubyが1.8.5だったときの絶望感ったらないね。
0956デフォルトの名無しさん
2011/02/08(火) 18:50:35どういう仕組みなの?それ
0957デフォルトの名無しさん
2011/02/08(火) 19:13:42おおー、ブロックなしだと、Enumeratorを返すようになったんだ。
0958デフォルトの名無しさん
2011/02/08(火) 20:05:33[nil].cycle と同じだし
p loop.take(5) #=> [nil, nil, nil, nil, nil]
p [nil].cycle.take(5) #=> [nil, nil, nil, nil, nil]
無限nil列って使い道あるのか?
with_indexしたところで、余分なnilが付いてくるし
0959デフォルトの名無しさん
2011/02/08(火) 20:41:56おいやめろ
0960デフォルトの名無しさん
2011/02/08(火) 22:57:000961デフォルトの名無しさん
2011/02/08(火) 23:13:390962デフォルトの名無しさん
2011/02/09(水) 01:05:19初期値を比較的安全に設定するために、指定された初期値を dupして代入しようとしましたが、
初期値が数値などの場合 dup で例外が発生します。
respond_to? でdupできるかどうか判別できるかとも思いましたが、dup できなくても true が返ってきます。
今は仕方がないので例外を捕捉して例外時はそのまま代入していますが
0963デフォルトの名無しさん
2011/02/09(水) 01:40:36xml = open(headline_url)
aa = REXML::Document.new(xml).root
このコードでxmlに<とか>が入ってるとパースエラーになってしまうんですがどうすればいいでしょうか
0964デフォルトの名無しさん
2011/02/09(水) 02:18:26ねとらじの運営にゴルァするのがベストかと
well-formedなXMLを送ってこいと
0965デフォルトの名無しさん
2011/02/09(水) 02:27:09xmlの必須要素である<>があるとエラーなんて、ライブラリとしてあってはならないバグだ
即刻バグ報告すべき
0966デフォルトの名無しさん
2011/02/09(水) 02:30:11ちゅっちゅ
0967デフォルトの名無しさん
2011/02/09(水) 07:43:46すみません勘違いでした
ちなみ>>963でかってに変換されてるんですけど>は&gt;、<は&lt;になっていて問題無いみたいです
実際は唐竍鰍ンたいな機種依存文字が入ってるいるとエラーになっています
0968デフォルトの名無しさん
2011/02/09(水) 09:09:14>>1
> ■質問する人へ
0969デフォルトの名無しさん
2011/02/09(水) 09:40:46・ dup も clone も浅いコピーであることについてここに判子押した上で実際に dup して rescue する
・ コストが高いことを理解した上で Marshal.load(Marshal.dump(arg)) する
・ 引数を複製しないと安心できないというのは70パーセントくらいの割合でデザインミスなので考え直す
お好きなものを張り切ってどうぞ
0970デフォルトの名無しさん
2011/02/09(水) 10:18:41headline_url = "http://yp.ladio.livedoor.jp/stats/list.xml"
xml = open(headline_url).read
xml = xml.sub!(/encoding="shift-jis"/){'encoding="CP932"'}
aa = REXML::Document.new(xml).root
でどうだ
0971デフォルトの名無しさん
2011/02/09(水) 10:22:58headline_url = "http://yp.ladio.livedoor.jp/stats/list.xml"
xml = open(headline_url).read
xml.sub!(/encoding="shift-jis"/){'encoding="CP932"'}
aa = REXML::Document.new(xml).root
もし使ってる iconv が Windows-31J を解釈できる非公式 iconv なのなら
指定するのは CP932 ではなく Windows-31J のほうがいい
もし、CP932 を指定しても Iconv::IllegalSequence の例外が出てしまう場合は…
0972デフォルトの名無しさん
2011/02/09(水) 10:34:28encoding="shift-jis" って宣言したなら Shift_JIS 以外の文字は入れないで頂きたい
@ABとか鰍ニかとかご法度
本当は REXML::Document.new(xml, :encoding=>'CP932') とか指定できるのが望ましいんだけど
そういう構造にはなってないなさすが原産地外国
ちなみに Nokogiri だと Nokogiri::XML.parse(xml, nil, 'CP932') で動作する
0973デフォルトの名無しさん
2011/02/09(水) 16:08:22ありがとうございます解決しました
機種依存文字は意識したこと無かったので勉強になりました
>>968
すいません気をつけます
0974デフォルトの名無しさん
2011/02/09(水) 19:23:39反応ありがとうございます。
3番目の設計見直しでいきます。
1番目は今のやり方です。浅いコピーだということは承知しておりまして、比較的安全にと書いたのはそういう意味です。言葉足らずでしたね
2番目、今回例外処理のコスト高を何とかしたいというのが動機でしたので。
active_supportではduplicable?を定義してますね。姑息な手段に思えます。ruby本体でサポートして欲しいなあ
0975デフォルトの名無しさん
2011/02/09(水) 19:34:16昨日見たときは "\x13" だかの変な制御コードがあって引っかかってたけど、今日見たら無くなってた
0976デフォルトの名無しさん
2011/02/10(木) 00:12:01スレ内容が全く理解できないという。
0977デフォルトの名無しさん
2011/02/10(木) 00:27:44if hoge && hoge.isXXX?
こんな操作を毎回やっているのですが、rubyらしい手法はありますか?
設計が悪いとかnullObject使えとかそういう感じなんでしょうか
0978デフォルトの名無しさん
2011/02/10(木) 00:38:00だせえ!やーいやーい!
0979デフォルトの名無しさん
2011/02/10(木) 00:44:59お前童貞だろ
0980デフォルトの名無しさん
2011/02/10(木) 00:50:57if param.is_foo? といきなり書くと param が nil だった場合 NoMethodError になってしまう
かと言って if param && param.is_foo? と書くのは正しいのだが冗長に見えて仕方がない
なんとかする方法はありませんか?
というような質問はしょっちゅう出るのだが、汎用な回答はない
if param && param.is_foo? と書くようにするのがいちばん無難
あとは NoMethodError が出ることを駄目データが出たメッセージとして許容するとか
0981デフォルトの名無しさん
2011/02/10(木) 01:28:45nullを返す場合があるメソッドを読んだ時にだけチェックすればいいのだ。
0982977
2011/02/10(木) 02:36:28なるほど、まあ無難と言われてちょっと安心です。
methodや機能それぞれについてアサーション(一般的な意味を含む)
をしっかり考えてそれを前提にすれば、nullチェックなどいちいち書かなくてもいい
という意見にも納得です。
0983デフォルトの名無しさん
2011/02/10(木) 02:37:020984デフォルトの名無しさん
2011/02/10(木) 02:56:35無意味なnilチェックでバグを見逃すことになる。
0985デフォルトの名無しさん
2011/02/10(木) 04:03:48nil が起こす NoMethodError はかなり特別だ
たいていの Ruby プログラマは、これを「nil かどうかチェックして分岐しとけよ糞が」とは思わない
むしろいわゆるシグナルとして残す
ホントは nil が起こす NoMethodError は特別扱いして名前付けて欲しいんだけども
0986デフォルトの名無しさん
2011/02/10(木) 05:00:38> nil が起こす NoMethodError はかなり特別だ
はあ?
> ホントは nil が起こす NoMethodError は特別扱いして名前付けて欲しいんだけども
はあ?
自称上級者気取りが初心者を混乱させるのはやめてほしいな
0987デフォルトの名無しさん
2011/02/10(木) 06:29:01息が臭いだけ。
0988デフォルトの名無しさん
2011/02/10(木) 07:52:310989デフォルトの名無しさん
2011/02/10(木) 07:54:13たいていis無しのxxx?にする
0990977
2011/02/10(木) 08:39:20?そのものはboolを返すという記号としては有りだと思うけど。
0991デフォルトの名無しさん
2011/02/10(木) 11:48:13Java だと、ぬるぽだな。これが一番わかりやすいかな。
C だとSegmentation fault になる。
segmentatino fault だと色々原因がありそうだけど、殆どがぬるぽなんだよな。
0992デフォルトの名無しさん
2011/02/10(木) 12:01:30ものによっては rescue で自前の例外を発生させてユーザーにわかりやすく知らせたりもするぬ
レス数が950を超えています。1000を超えると書き込みができなくなります。