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

Ruby 初心者スレッド Part 39

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2010/10/21(木) 10:06:13
プログラミング言語Rubyについての、初心者向けスレです。質問・要望・雑談などどうぞ。

★注意★ Ruby 1.9.2 は初心者には若干時期早尚です。初心者には Ruby 1.8.7 を強くお勧めします。
 文字エンコーディング等の外部基礎知識が必要な上、不完全対応の第三者ライブラリでの問題の切り分けが手間です。
 1.8.7 は 1.9 系の新機能のいくつかが利用可能なため、1.8.7 を習得すればスムーズに 1.9 系に移行できるでしょう。

関連スレや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を読め」でいいので、叩かない&怖がらせない。
 ・わけわかな質問にもエスパー発揮で。できれば質問の仕方を教えるぐらいで。
 ・自信がない回答ならその旨表明すること。誤った回答は初心者じゃ見抜けない。
0153デフォルトの名無しさん2010/10/28(木) 00:26:36
>>86
conn.execはPGresultクラスが帰ってくるのでclear必須。
conn.queryの場合はArrayクラスが帰ってくるのでclearはいらない。
0154デフォルトの名無しさん2010/10/28(木) 09:33:30
こんな機能がキラー扱いされちゃう1.9って
0155デフォルトの名無しさん2010/10/28(木) 10:02:28
>>152
それは対応するendを見つけた上で表示されるの?そうだったらすごい。
Emacsでは最後のendのところで間違えてますマークがつくだけだから、
どこで間違えてるかは自力で見つけなきゃいけない。
だから>>134は便利だった。
IDEだったら、たとえば>>134では5行目の横に間違えてますマークがつくの?
それはぜひ初心者に教えたいので、IDE名教えて。
0156デフォルトの名無しさん2010/10/28(木) 10:50:33
Nokogiri の、この↓機能を使おうと思ってるんだけど、

doc = Nokogiri::XML(File.read('some_file.xml'))
xslt = Nokogir::XSLT(File.read('some_transformer.xslt'))
puts xslt.transform(doc)

XML が外部サーバーにある場合はどうしたらいいですか?
一旦ローカルにダウンロードして XSLT 適用する…ぐらいしか思いつかないけど、
そんなはずない気がするし。すみません、お願いします。
0157デフォルトの名無しさん2010/10/28(木) 11:38:00
…Rubyの基本ライブラリの勉強してから外部ライブラリ使え
0158デフォルトの名無しさん2010/10/28(木) 11:54:06
おまじないに見えてしまってるんだろう

File.read(path) はファイルパス path の内容をディスクから読み込んで文字列で返す
Nokogiri::XML() は引数に文字列を取るからうまく合致するわけだな
だからやっぱり文字列を返すメソッドの返り値を指定するしかあんめえ
0159デフォルトの名無しさん2010/10/28(木) 12:12:13
>>157
なるほど!そうします。
常識レベルのことなのでしょうが、自分にはありがたいです。
ありがとうございます。

>>158
なんとな〜くわかった気がします。
File.read(Path) というカタチにこだわらず、Nokogiri::XML() に
XML ファイルの中身(文字列)を渡してあげればいいということでしょうか。
やり方がわからないので >>157 さんの言われるとおり、標準ライブラリの勉強をしてみます。
ありがとうございます、助かりました。
0160デフォルトの名無しさん2010/10/28(木) 12:44:43
>>157
>>158
いちおう解決できました。
実は net/http で XML の内容を取得することは出来ていたのですが、
doc = Nokogiri::XML(response.body)
とやってもうまくいかなかったので、なにか根本的に
間違っているのだろうと思い、質問させていただいたのでした。

おそらく正しいやり方ではないのでしょうが、
response.body をグローバル変数に代入して
doc = Nokogiri::XML($hoge)
とやってみたらとりあえず意図する結果が得られました。
ありがとうございました。
0161デフォルトの名無しさん2010/10/28(木) 12:45:25
めんどくさいし require 'open-uri'; URI.parse("http://www.2ch.net/").read でいいよね
0162デフォルトの名無しさん2010/10/28(木) 16:48:23
Threadを使って並列に処理させるプログラムを作ろうと思っています。
あるサイトにあったソースを実行してみたところ問題が起きました。
def foo(name)
20.times do
print name
print " "
end
end

def test1
t1=Thread.new{foo("a")}
t2=Thread.new{foo("b")}
t1.join
t2.join
end
test1
実行してみると
a a a a a a a a a a a a a a a a a a a a b b b b b b b b b b b b b b b b b b b b
となってしまい、これではThreadにした意味がなく困っています。
rubyのバージョンは1.8.7です。
0163デフォルトの名無しさん2010/10/28(木) 16:58:19
めんどうだから全く試してないけど

print name

を20回ごとき超一瞬なんだから、
1回ごとにsleepとか入れないとそういう結果になってもおかしくないと思うけど。
0164デフォルトの名無しさん2010/10/28(木) 17:00:14
スレッドt2が動き始めるまでに
スレッドt1の実行が終わっちゃうからですよ
処理内容が軽すぎるのが要因
繰り返しを数百以上にするとか
sleep 0.1
をはさんでみるとか

あとはスレッドの切り替わるタイミング
Ruby1.8.7だと混ざらないけど
1.9だとそのままでもちゃんと混ざりますよ
1.9ではスレッドの実装方法が変更されたので
0165デフォルトの名無しさん2010/10/28(木) 17:04:13
おなかすいてきたしめんどくさいから検証してないが、
標準入力に何かを表示するプログラムはスレッドの検証にまったく向いてない
最初に
$stdout.sync = true
してから試せ
0166デフォルトの名無しさん2010/10/28(木) 17:07:00
Aがcpuを占拠中にBの仕事が入ってこないんじゃテストの意味ないな。
0167デフォルトの名無しさん2010/10/28(木) 17:21:36
>>163>>164
簡潔に説明しようと思い、省いてしまいましたが
timesの回数を10万などに増やしましたがしかし結果は
t1のスレッドの処理が終わってからt2という流れになってしまいます。
sleepを入れたとこ
ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab
のような結果になりました。
ただ何度実行してもこの結果というのはrubyのスケジューリングの仕様なんでしょうか?
取り敢えず1.9にしてもう一度試してみます。

>>165
入れたところ処理されるごとに表示されました。

みなさんありがとうございます!!!
0168デフォルトの名無しさん2010/10/28(木) 17:49:13
>>165
それはリアルタイムに起きているなにかを確認したいときで
今回のはおなじ出力バッファに書き込んでいく順序をみたいのだから
あまり関係ないんじゃないの
と、$buff = '' でprintの代わりに$buff.concatするようにしたら
文字列に追加するコストが軽すぎるのか
1.9でも a 20個の後に bになってしまった
ここはやはりsleepを入れとけって事で

>>167
ruby 1.8.7 (2009-06-12 patchlevel 174) [i386-mingw32]だと
200.times程度でも混ざるんだけどな
0169デフォルトの名無しさん2010/10/28(木) 17:55:15
逆に詳しい人に質問
1.8以前だと実際に動いているのは一つだけで
Ruby自身が適当な間隔でスレッドを切り替えながら実行している
1.9だと複数スレッドがネイティブに複数動いてるけど、GILがあるので
ある一つのスレッド以外のスレッドはGILの開放待ちしてる
IO処理とかの一部Ruby外の処理ではGILを開放するので並列動作するときもある
って理解であってるの?

InfoQのRubinius 1.1の記事読んだら
将来RubiniusもGILを使わないようにするので
Ruby実装の中でGILがあるのはMRIだけになる
と、あったんだけど
JRubyやIronRubyって今でも並列動作するの?
Windows版のMRIしか知らんのもので
0170デフォルトの名無しさん2010/10/28(木) 19:23:21
ruby1.9.2、rails3 を使っております。 eachで質問させてください。

下記のようにeachで回すと、なぜかhash全体の内容も最後に表示してしまいます。
この場合、指定した coupon_idの数値のみを表示するにはどうすればよいでしょうか?

※view内のコード

<% hash = [{"coupon_id"=>"2247", "coupon_area"=>"東京",},
{"coupon_id"=>"2254", "coupon_area"=>"東京",}] %>
<br>
<%= hash.each do |item| %>
<%= item['coupon_id'] %>
<br>
<% end %>

※結果

2247
2254
[{"coupon_id"=>"2247", "coupon_area"=>"東京"}, (ここがいらない)
{"coupon_id"=>"2254", "coupon_area"=>"東京"}] (ここがいらない)
0171デフォルトの名無しさん2010/10/28(木) 19:55:54
Railsは知らないのだけど
4行目が
<%= hash.each do |item| %>
じゃなくて
<% hash.each do |item| %>
じゃないの?
0172デフォルトの名無しさん2010/10/28(木) 21:42:59
なおりました
ありがとうございました
0173デフォルトの名無しさん2010/10/29(金) 01:00:27
>>171
<% %> と <%= %> はたしかに間違えやすい
これはeRuby仕様の失敗だった
0174デフォルトの名無しさん2010/10/29(金) 01:02:46
>>155
横からだが>>134のコード試してみた。
NetBeans 6.9では最後にエラーマークが付くだけだったわ、残念

if endやdo endの対応括弧の強調表示もあるけど、
他のエディタにもあるし、それではわかりにくいということだよな

indent-region相当の自動インデント使うと予想通り1つendがないずれたインデントになってわろたw


それよりもヒント機能で式?が1個しか無いからifを後置にするか聞いてきたのがおもしろかった
変化後のプレビュー表示できたりIDEは無駄に豪華な機能あるよな。
リファクタリング系の機能なんだろうけど
0175デフォルトの名無しさん2010/10/29(金) 01:08:46
>>173
あまり関係ないが、
Rails 3より前はformやform_forなどform類のヘルパーが<%= %>じゃなくて、<% %>だったり疑問があったが、
Rails 3から<%= %>に統一されたな

どっちにしろ、<%= と <% はちょっとわかりにくい。見かけが
初心者に他のtemplateエンジンをつかえというのもねえ
0176デフォルトの名無しさん2010/10/29(金) 07:41:29
<% %>
<%print( )%>

これで一目でわかる!
0177デフォルトの名無しさん2010/10/29(金) 07:46:49
っつーか hash.each が戻り値を持つからおかしなことになるんだよ
0178デフォルトの名無しさん2010/10/29(金) 08:15:26
<%= をハイライト表示するよう表示するエディタを使っている。
0179デフォルトの名無しさん2010/10/29(金) 08:28:04
<% %><%= %> はASPのまね?
0180デフォルトの名無しさん2010/10/29(金) 08:29:35
そう
0181デフォルトの名無しさん2010/10/29(金) 08:49:58
>>178
なるほど、それいいな。採用。
0182デフォルトの名無しさん2010/10/29(金) 09:03:05
>>177
君のeachはまたforの書き換えのようだな
0183デフォルトの名無しさん2010/10/29(金) 09:13:35
find_all「フフフ…奴は我らコレクションメソッド四天王の中でも一番の小物…」
map「(…え?)」
inject「(創立メンバーだよねあの人)」
01841702010/10/29(金) 10:55:28
>>171

ありがとうございます!上手くいきました!
01851702010/10/29(金) 10:57:09
>>175

そうなんです。Rails3から <%= %>に統一されたと
本に書いていたので、すべて <%= %>で記述してよいと思っていたのです。
0186デフォルトの名無しさん2010/10/29(金) 11:11:05
うおーオマジナイ厨がー
0187デフォルトの名無しさん2010/10/29(金) 11:22:39
each文の書き方は do end か { } を使う方法、
どちらがスタンダードなのでしょうか?

netbeansの入力補助では { } のほうが出てきますが、 do end のほうが
よく説明では見るような気がします。
0188デフォルトの名無しさん2010/10/29(金) 11:23:30
標準はない
0189デフォルトの名無しさん2010/10/29(金) 11:39:24
do end
0190デフォルトの名無しさん2010/10/29(金) 11:46:34
>>187
1行で書けるブロックの場合はかなりの割合で { }
直後にドットでメソッドチェーンを繋げる場合はほぼ確実に { }

each の用途的に each do ... end が多くなるとは思う
0191デフォルトの名無しさん2010/10/29(金) 11:47:39
>>187
自分ルールでは、1行で収まる場合は、{ }
複数行になる場合は、do end
01921872010/10/29(金) 11:53:03
すごく参考になりました。
みなさんどうもありがとうございます。
0193デフォルトの名無しさん2010/10/29(金) 13:07:36
引数objに対しメソッドA メソッドBを希望するメソッドXが
あったとしてメソッドXがそれを必要とすることをどうやって調べてる?
更にメソッドXがメソッドAにメソッドCを期待してるときもどう判断してんの?
メソッドXをひたすらトレース?
0194デフォルトの名無しさん2010/10/29(金) 13:10:52
よくわからんが依存はマニュアルに書いとけ
0195デフォルトの名無しさん2010/10/29(金) 13:10:54
間違えた
×メソッドAにメソッドCを期待
○メソッドAにメソッドCをもつオブジェクトを返す事を期待
0196デフォルトの名無しさん2010/10/29(金) 13:21:50
>>149
書くとしてどう書くのが理想かな。
結局C++のコンセプトみたいになんのかな。
0197デフォルトの名無しさん2010/10/29(金) 13:31:33
def m(param)
s = param.read
s.scan...
end

だとして、メソッド m の引数 param は read メソッドが動作しないと困る、と
これをどう「書き手」へ知らせるかというと、やっぱりマニュアルに書くしかないと思う
メソッド m の名称を read 可能な引数を取りそうな名前にするとか
引数 param の名称を read しそうな名前にするとかもあるが、確実性はかなり低くてオナニーレベル

一応 Ruby スクリプトとしては respond_to? が使用できるが、
複雑な特定の条件分岐をするのでない限り、
「param に read メソッドなんてありませんが何か」という NoMethodError を出すのと本質的にも対処的にも変わらない

def m(param)
if param.respond_to?(:read) then
s = param.read
else
raise ArgumentError "wrong type argument (needs READable)"
end
s.scan...
end
0198デフォルトの名無しさん2010/10/29(金) 14:47:26
問題は公式のマニュアルも適当なところだな。
「引数○○には××を指定します」と書いてあったので文字列渡したら動かなくて
サンプルコード検索したらシンボルでブチキレ
0199デフォルトの名無しさん2010/10/29(金) 15:00:38
フィードバックしなきゃ改善されないんだが
0200デフォルトの名無しさん2010/10/29(金) 15:02:23
凡人はRubyという素晴らしいツールを手に入れたとしても
数十年来の「型チェック」の呪いからは結局逃れられないのですよ
arg.kind_of?
arg.respond_to?
0201デフォルトの名無しさん2010/10/29(金) 15:07:18
つまり回答はこうか

>>193
オブジェクトの持っていないメソッドを呼ぶとRubyは例外を発生させて報せるから問題ない
0202デフォルトの名無しさん2010/10/29(金) 15:14:53
>>201
正確に言うなら「静的に保証する方法はない」って所か
食わせる引数を雰囲気で想像して、テストにかけろ
かなり適当だが意外にうまくいくのがダックタイピングの経験的根拠

Scalaならできるんだっけ?
0203デフォルトの名無しさん2010/10/29(金) 15:45:47
文字列を要求するメソッドが文字列以外を渡されたときto_sしちゃだめなの?
0204デフォルトの名無しさん2010/10/29(金) 15:55:00
>>203
ホントはあまりよくないが、別に悪いわけでもない
arg.to_s.dup ... と続くメソッドは意外とある
「極力文字列に変換して処理します」と解説つけてればOK

「String以外が渡ったら内部のどっかでエラーが出るだろう」
という期待をしているスクリプト作者もいることを忘れてはならない
0205デフォルトの名無しさん2010/10/29(金) 17:05:44
each を使って、hashに値を追加していきたいです。

下記のようなコードでは上書きされてしまい、最後の値だけ記録されて
しまうのですが、正しいやり方はどうすればよいでしょうか?

def self.get_goods

hash = [{"id" => "500",},{"id" => "60"}]

goods = Hash.new

hash.each do |item|
goods['id'] = item['id']
end

return goods
end
02062052010/10/29(金) 17:11:40
array だと pushメソッドで値を追加できたのですが。。
0207デフォルトの名無しさん2010/10/29(金) 17:12:49
Hash のメソッド全部読め
Hash オブジェクトに対する登録の仕方を勉強するんだ
0208デフォルトの名無しさん2010/10/29(金) 17:19:55
そういうことをしたければハッシュの中身を配列にする。
1つのキーに対して複数の値を格納する能力をHashは持ってない。

hash = {"id" => ["500", "60"]}

ていうかよく見たら hash = [{"id" => "500",},{"id" => "60"}] って、中身にハッシュが入ってる配列だよね。
何をどうしようとしてそんなもん作ったわけ?
02092052010/10/29(金) 17:32:11
>>207

もう一度レシピブックを読んで、goods = Hash.new{|h, key| h[key] = [] }
のようなやり方を試してみたところ、一応全部追加できました!

しかし、どうも並び順がおかしい。。


>>208

ありがとうございます。
実は、JSON形式で取得したものを配列に変換したために、
こんな形になっているのです。

なので、中身を配列にすることが無理かもしれません。。

うーむ、どうしようもない。。
0210デフォルトの名無しさん2010/10/29(金) 18:35:30
MRI 1.9では *たまたま* 追加した順序になるような実装を使用しているが、
本来 hash に並び順はないものと理解すべき。
0211デフォルトの名無しさん2010/10/29(金) 18:51:36
>>210
順序は保存されます
0212デフォルトの名無しさん2010/10/29(金) 18:57:51
>>210みたいな人って「Integerとはそもそも本来整数で〜」とか言ってそう
0213デフォルトの名無しさん2010/10/29(金) 19:00:16
>>210の人気に嫉妬

というかPerl由来とはいえハッシュという命名自体が今となっては以下略
0214デフォルトの名無しさん2010/10/29(金) 19:08:37
>>213
> ハッシュという命名自体が
$ irb
irb(main):001:0> p hash
-607941458

…?

というか>>205みたいなスクリプトを見るといつかどっかで爆発しそうで気になって仕方がないw
0215デフォルトの名無しさん2010/10/29(金) 19:13:49
class や id という変数名もめんどくさい
end に至っては同名のローカル変数を end の形で使うことも(ふつうは)できない
0216デフォルトの名無しさん2010/10/29(金) 21:55:11
>>210
スクリプト屋じゃないせいかHashか格納領域(コレクション)と
結びつかん。
データが異なることは示すがデータが同じ事は保証しない値。
そういう見方だな。
0217デフォルトの名無しさん2010/10/30(土) 04:28:54
初心者に1.8.7オススメって無責任なことテンプレに書いたの誰?
過去の資産を引きずっていない真っ白な初学者こそ
最新の1.9.2から始めるべきでしょうよ。
0218デフォルトの名無しさん2010/10/30(土) 04:59:13
>>217
それが正しい、1.9を勧めるおまえは間違ってるからこのスレから去れと言って、
執拗に1.8.7を推奨してたやつ。知らんの?
>>210みたいなやつ。同一人物かもw
0219デフォルトの名無しさん2010/10/30(土) 05:13:44
Hello, Ruby!
と結果に表示させた後に3秒後に結果が消えるようにするにはどうすればいいんでしょうか?
0220デフォルトの名無しさん2010/10/30(土) 05:17:11
八ッシュの中にいくつか入った数値の合計をプログラム上で計算して、
それをまた同じ八ッシュ内に入れるにはどうすればいい?

0221デフォルトの名無しさん2010/10/30(土) 05:18:26
もうすこし仕様を厳格に記述してくれ
02222202010/10/30(土) 05:28:09
データが
1月 500 400 300
2月 400 200 100
みたいな感じで、

そのデータの月部分がハッシュのキーで、バリューは400 200 300の部分。
で、プログラム上で400足す200足す300の計算をして、
その合計(900)をまたハッシュ[1月]に入れなきゃならないんだ。

ちなみに元の400 200 300はそのまま残したい。

こんなので良いでしょうか?


‥説明下手でごめんねorz
0223デフォルトの名無しさん2010/10/30(土) 06:04:50
元が "400 200 300" なのか ["400", "200", "300"] なのか [400, 200, 300] なのかわからんし
合計を "400 200 300 900" と同列にするのか [[400, 200, 300], 900] みたいに別にするのかもわからん
それと{"1月"=>[400, 200, 300]} と {"1月"=> 900} を別にせず同じハッシュに入れる意味も
0224デフォルトの名無しさん2010/10/30(土) 07:56:34
>>222
そんな説明じゃわからない。
そのデータでなんで400+200+300を計算するの?
1月なら500+400+300だし、2月なら400+200+100じゃないの?
ハッシュはどんな構造になっているの?かりに
{ "1月" => [500, 400, 300], "2月"=>[400, 200, 100] }
だとして、900を追加したら
{ "1月" => [500, 400, 300, 900], "2月"=>[400, 200, 100] }
になるけど、これでいいの?

#上司がこんな仕様もってきたらぶちきれる。
0225デフォルトの名無しさん2010/10/30(土) 08:27:51
>>220,222
出力データの形式(仕様)が定義されていないいから、適当に作ってみた。
もし明確にしてくれれば、書き直すよ。

def calc(input_data)
 Hash[
  *input_data.map { |month, items|
   [
    month,
    {
     :orig => items,
     :sum => items.inject(0) { |result, item| result + item }
    }
   ]
  }.flatten
 ]
end


(irbでの実行例)

$ irb -rcalc.rb
irb(main):001:0> p calc({ 1 => [500, 400, 300], 2 => [400, 300, 200] })
{1=>{:orig=>[500, 400, 300], :sum=>1200}, 2=>{:orig=>[400, 300, 200], :sum=>900}}
=> nil
irb(main):002:0>
0226デフォルトの名無しさん2010/10/30(土) 08:43:34
爆釣れだな
02272252010/10/30(土) 08:44:54
>>224は(副作用の無い)関数型のコードだったけど、同じ処理を手続き型で書き直してみた。
こちらの方が効率は良いし、おそらく理解し易いと思う。(実行結果は>>224と同じなので省略)

def calc2(input_data)
 output_data = Hash.new

 input_data.each { |month, items|
  sum = 0
  items.each { |item| sum += item }

  output_data[month] = { :orig => items, :sum => sum}
 }

 output_data
end
0228デフォルトの名無しさん2010/10/30(土) 08:46:29
>>219
Ruby の範疇外だな
ああ、Rubyで3秒待つのは sleep(3) でできる
それ以外のことは「表示した先」のマニュアルをご覧になって、system() あたりで指示してください
02292252010/10/30(土) 09:27:15
>>222
>‥説明下手でごめんねorz

データ構造の仕様を明確に(=形式的に)記述する手法はいくつかある。以下はBNFと呼ばれる書き方。
(もしBNFを知らなければ、Wikipedia等で勉強してね)

 <入力データ> ::= <入力レコード>*
 <入力レコード> ::= <月> <項目>*

 <出力データ> ::= <出力レコード>*
 <出力レコード> ::= <月> <出力レコード本体>
 <出力レコード本体> ::= <項目>* <合計>

 <月> ::= 文字列
 < 項目 > ::= 整数
 < 合計 > ::= 整数

他にも、今回のケースだと(IntegerやStringといった)基礎オブジェクトの他には
ArrayとHashしか使われていないから、JSONやYAMLのスキーマ定義言語で代用してもいい。
・JSONの可能性がグンと拡がるぞ! JSONスキーマ - 檜山正幸のキマイラ飼育記
  http://d.hatena.ne.jp/m-hiyama/20090413/1239581682
・Rubyist Magazine - プログラマーのための YAML 入門 (検証編)
  http://jp.rubyist.net/magazine/?0012-YAML

あるいは、MLやHaskellのような「強いデータ型」の言語の記法でもいい。
(ちなみに、Haskellの記法はRubyリファレンスのメソッド定義記法として利用されている)

おそらくこのスレを覗いている人であれば、これらのいずれかで書けば、理解してくれると思うよ。
0230デフォルトの名無しさん2010/10/30(土) 09:36:18
そんなの日本語で書けばいいじゃん

  [
  5月 => [第1週金額, 第2週金額, 第3週金額, ..],
  6月 => [第1週金額, 第2週金額, 第3週金額, ...],
  7月 => [第1週金額, 第2週金額, 第3週金額, ...],
  }
 で月ごとの合計金額を出して
  {5月 => 5月合計, 6月 => 6月合計, 7月 => 7月合計, }
 というハッシュを作りたいです

とかいうののどこにわかりにくくなる余地があるんだ
0231デフォルトの名無しさん2010/10/30(土) 11:10:03
日本語の便利なとこだな
02322202010/10/30(土) 11:39:46
力尽きて寝て起きたら凄い事に。

とりあえず今から参考にして頑張ってきますノシ

ありがとー。
0233デフォルトの名無しさん2010/10/30(土) 11:40:45
>>230
さすがエスパー
02342202010/10/30(土) 12:01:56
一応補足しておきます〜


{ "1月" => [1週目売上, 2週目売上…], "2月"=>[1週目売上,2週目売上…] }
ってハッシュがあって、
売上合計を求めてそれを
{ "1月" => [1週目売上, 2週目売上…,売上合計], "2月"=>[1週目売上,2週目売上…,売上合計] }
で、最後に

  月     1週目売上   2週目売上  〜  売上合計
のように出力したい。
出力の際は売上合計をソートした状態で、売上合計が高い順から表示させる

って感じです。      
0235デフォルトの名無しさん2010/10/30(土) 12:09:56
>{ "1月" => [1週目売上, 2週目売上…,売上合計], "2月"=>[1週目売上,2週目売上…,売上合計] }
この構造は超無駄
「端っこ」を特別欄扱いする表計算思考は捨てなされ

{ "1月" =>
{売上 => [1週目売上, 2週目売上…],
合計 => 1月合計},
"2月" =>
{売上 => [1週目売上, 2週目売上…],
合計 => 2月合計},
...}
みたいなのがとりあえず妥当

data.each do |month, h|
sales = h[売上].join("\t")
sum = h[合計]
puts "#{month} \t #{sales} \t #{sum}"
end

こんなんでなんとかなんね?
0236デフォルトの名無しさん2010/10/30(土) 12:19:37
あ、ソートするって書いてあったな

data.sort_by{|month, h| h[合計]}.reverse_each do |month, h|
sales = h[売上].join("\t")
sum = h[合計]
puts "#{month} \t #{sales} \t #{sum}"
end
0237デフォルトの名無しさん2010/10/30(土) 12:23:51
Rubyでは、下記のPHPのように、連想配列にループで値を順番に追加
するにはどうすればよいでしょうか?

for ($i = 0; $i < $itemNumberLimit; $i++){
$items[$i]["url"] = $currentXml -> Items -> Item[$i] -> DetailPageURL;
$items[$i]["image"] = $currentXml -> Items -> Item[$i] -> LargeImage -> URL;
}
0238デフォルトの名無しさん2010/10/30(土) 12:28:58
items = current_xml.items.map {|item| { 'url' => item.detail_page_url, 'image' => item.large_image.url } }
0239デフォルトの名無しさん2010/10/30(土) 12:32:46
>>237
正直、ループ内で値作って追加とかそのへん綺麗に書けなくて苦手なのだ

h = {}
keys = ['k1', 'k2', 'k3']
values = ['v1', 'v2', 'v3']
として
new = Hash[keys.zip(values)]
h.update(new)
とか
keys.each_with_index do |k, index|
h[k] = values[index]
end
とか
02402372010/10/30(土) 12:42:33
>> 238 >>239
即レス、どうもありがとうございます。

むむむ、結構難しいですね。
ただいま、レシピブックなどを参照して格闘中です。
02412252010/10/30(土) 14:16:10
>>234
最終的な出力形式に合わせて変更してみた。ただし、中間データの形式は、
(>>234の「ハッシュのハッシュ」ではなく、)「ハッシュのリスト」にしている。

def calc3(input_data)
 input_data.map { |month, sales|
  {
   :month => month,
   :sales => sales,
   :sum => sales.inject(0) { |result, sale| result + sale }
  }
 }.sort_by { |record|
  record[:sum]
 }.reverse.each { |record|
  month = record[:month]
  sales = record[:sales]
  sum = record[:sum]

  printf("%2d月 %s %4d¥n",
   month,
   sales.map { |sale| format("%3d", sale) }.join(' '),
   sum
  )
 }

 nil
end

(実行結果は次のカキコで)
02422252010/10/30(土) 14:17:19
(>>241の実行結果)

$ irb -rcalc3.rb
irb(main):001:0> calc3({ 1 => [500, 400, 300], 2 => [400, 300, 200] })
1月 500 400 300 1200
2月 400 300 200 900
=> nil
irb(main):002:0>
0243デフォルトの名無しさん2010/10/30(土) 14:29:59
>>240
いきなりだとワケワカだから

items = []
for i in 0...limit do
items[i] = {}
items[i]['url'] = url
items[i]['image'] = image
end

くらいから始めればいい(上のも ... がちと罠くさいが)
0244デフォルトの名無しさん2010/10/30(土) 14:41:50
>>243
コレクションの意味を失わせる上に現状誰も使っていないforにわざわざ誘導する意味は何?
「RubyでHTMLを記述するにはcgi.rbが便利です」とか言われたら怒るだろ
0245デフォルトの名無しさん2010/10/30(土) 15:18:53
>>229
全然関係ないが、HTMLがその形式だったら閉じタグもいらないしファイルサイズも減るしいいことづくめだったのにな
HTMLは可読性が最悪になってしまった
0246デフォルトの名無しさん2010/10/30(土) 15:21:23
>>244
あまりにも違うと、もとのと対応がとれなくて必要以上に理解が困難になるから。
だから「から始め」と書いてある。

02472202010/10/30(土) 15:58:19
おかげでなんとか出来たよー
ありがとうございましたーノシ
0248デフォルトの名無しさん2010/10/30(土) 18:37:55
rubyの資格ってどれくらい意味あると思う?
こんなかで持ってる人どれくらいいる?
0249デフォルトの名無しさん2010/10/30(土) 18:43:31
>>248
話のネタになる
それ以上の意味はないが、会話のきっかけを生めるという点でけっこう貴重
他の資格ではなかなかこうはいかない
0250デフォルトの名無しさん2010/10/30(土) 19:10:11
>>249
たしかに自分がRubyに興味がある、好きであると伝える手段としてはかなり良さそうですよね
0251デフォルトの名無しさん2010/10/30(土) 22:12:03
>>248
会社で5人とってもらってインテグレータになるのを目指してます。
ちょっとした会社の宣伝になる。
0252デフォルトの名無しさん2010/10/30(土) 22:47:23
>>251
なるほど、個人としてしか考えてませんでしたが、そういうのもあるんですね
silverが5人でいいのかな?goldだとむずかしそう
■ このスレッドは過去ログ倉庫に格納されています