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

Ruby 初心者スレッド Part 41

■ このスレッドは過去ログ倉庫に格納されています
0001京 ◆SsSSsSsSSs 2011/02/10(木) 13:47:51
プログラミング言語Rubyについての、初心者向けスレです。質問・要望・雑談などどうぞ。

★注意★ 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を読め」でいいので、叩かない&怖がらせない。
 ・わけわかな質問にもエスパー発揮で。できれば質問の仕方を教えるぐらいで。
 ・自信がない回答ならその旨表明すること。誤った回答は初心者じゃ見抜けない。
0348デフォルトの名無しさん2011/03/07(月) 18:46:55.69
>>346
そこまで大多数にエッジ追いかけてもらって意味のある大人気のソフトウェアじゃないしなあ
クライアントプログラムなら開発版バイナリ公開するのにも意義があるけど、スクリプト言語ではな…

ちなみに、ある程度のマシンスペックがあればRubyのコンパイルは現実的な時間で終わる
ナイトリーはアレだが、週1で更新して遊んで試すということは可能
バイナリ公開されてないだけで、自分用のを適宜開発最新版にしてる人はいるはず

「誰も日本語をpで表示して使ってなかったZEやっちゃったZE!」というエンバグの過去があるので、
ある程度知識のある人が開発版コンパイルして日常使用してもらうのは実はありがたい
ただ、初心者スレ向きの話じゃないなw
0349デフォルトの名無しさん2011/03/07(月) 19:10:16.58
>>346
人手が足りてないとか何とか
(まあ人手が足りてるオープンソースなんてあるのか知らんが)
0350デフォルトの名無しさん2011/03/07(月) 19:24:21.82
最新版おっかけるような人に求められてるスキルとして、
自力でビルドできる、とかは当然含まれてるので、ナイトリービルドのバイナリとか
あまり意味がない。
0351デフォルトの名無しさん2011/03/07(月) 19:28:29.89
確かWindows環境だともう入手困難なかなり昔のコンパイラが必要なんだっけ?
VC++ 6あたりだっけか
0352デフォルトの名無しさん2011/03/07(月) 19:29:20.36
>>348
/opt 以下にインストールしちゃえという事で、自前コンパイルしてたけど、仮想環境内で
ものの5分くらいでコンパイルは終わってた気がする
0353デフォルトの名無しさん2011/03/07(月) 19:31:46.98
>>351
mswin32 を今から環境そろえて作るのはもう無理
今からやる人は mingw になると思う

コンパイル経験さえあれば怖くないので興味のある方はどうぞ
0354デフォルトの名無しさん2011/03/07(月) 19:53:53.39
Rubyは不親切な人が多いのですね
最新版あげてくれたらいいのに
0355デフォルトの名無しさん2011/03/07(月) 19:54:25.78
諸先輩方に悩みを聞いて頂きたく、筆をとらせていただきました。
テキスト形式で出納帳をつけており、スクリプトで月別に集計しています。
先日、Ruby のバージョンにより計算時間が4倍ほど異なることに気が付きまして、
どのように修正すれば良いのかアドバイスを頂きたいのです。

ずいぶんと昔に例題をコピーして書いたものなので、実は自分でも何をしているのか
忘れてしまいました。根本的に誤っているのであれば、サンプルのようなもを教えて
頂けると助かります。

1.スペック
マシン: 600MHz, 384MB
Ruby : $ /usr/bin/ruby --version
ruby 1.6.8 (2002-12-24) [powerpc-darwin7.0]
$ /usr/local/bin/ruby --version
ruby 1.9.2p180 (2011-02-18 revision 30909) [powerpc-darwin7.9.0]
出納帳: UTF-8 768KB 11013行
自分 : 40 童貞
03563552011/03/07(月) 19:55:20.94
2.実行結果
$ time /usr/bin/ruby suitou.rb 2000
2000.01月の支出額 253421 円
...
2000.12月の支出額 345123 円
------------------------------------------
2000年の支出総額 3946492 円

real 0m1.285s
user 0m0.980s
sys 0m0.070s

$ time /usr/local/bin/ruby suitou.rb 2000
2000.01月の支出額 253421 円
...
2000.12月の支出額 345123 円
------------------------------------------
2000年の支出総額 3946492 円

real 0m4.456s
user 0m3.720s
sys 0m0.120s

3.出納帳(suitou.csv)
2000.01.01,1000,食費,外食,メイド喫茶,*
2000.02.02,2000,教養,HなDVD,立花書店,*
2000.03.03,3000,交通費,地獄-天国,Rails,*
...
03573552011/03/07(月) 19:58:55.81
4−1.スクリプト
#!/usr/bin/ruby
# -*- coding: utf-8 -*-
# Created by: Cherry 2002.06.26
# Last modified: 2010.04.15

ref_file = "/Users/cherry/suitou.csv"
sum = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
sougaku = 0

$pat = ARGV.shift

hoge = ["#{$pat}.01", "#{$pat}.02", "#{$pat}.03", "#{$pat}.04",
"#{$pat}.05", "#{$pat}.06", "#{$pat}.07", "#{$pat}.08",
"#{$pat}.09", "#{$pat}.10", "#{$pat}.11", "#{$pat}.12"]
03583552011/03/07(月) 19:59:38.08
4−2.スクリプト
open("#{ref_file}") {|file|
while l = file.gets
if l =~ /^#{$pat}/
hairetsu = l.split(/,+/)
for i in 0..11
if hairetsu[0] =~ /#{hoge[i]}/
sum[i] += hairetsu[1].to_i
end
end
end
end
}

for j in 0..11
puts "#{hoge[j]}月の支出額 #{sum[j].to_s.rjust(6)} 円"
sougaku += sum[j]
end

puts "------------------------------------------"
puts "#{$pat}年の支出総額 #{sougaku} 円"
0359デフォルトの名無しさん2011/03/07(月) 20:22:51.18
open(ARGF.filename + ".ecc") {|file|
while l = file.gets
l=l.to_i
ls=@I[ii]
ii=ii+1

lines += 1
fields += l.to_s.split(',').size
l^=(@P_y%(2**8*ls))
for i in 0..31
salt[i]=0
end
while(l>0)
i=0
while(i<ls)
salt[i]=l&0xff
salt[i]=sprintf("%c",salt[i])
l=(l>>8)
i=i+1
end
end
i=ls-1
while(i>-1)
g.write(salt[i])
i=i-1
end
end
これをCで書くとどうなりますか?教えてください。よろしくお願いします。
0360デフォルトの名無しさん2011/03/07(月) 21:11:25.25
あれ、あまり速くならない

# -*- coding: utf-8 -*-
ref_file = "/Users/cherry/suitou.csv"
sums = {"01" => 0, "02" => 0, "03" => 0, "04" => 0, "05" => 0, "06" => 0,
"07" => 0, "08" => 0, "09" => 0, "10" => 0, "11" => 0, "12" => 0}
sougaku = 0

target_year = ARGV[0]
re_target_year = /^#{target_year}/

open("#{ref_file}") {|file|
while line = file.gets
if line =~ re_target_year
hairetsu = line.split(/,+/)
if hairetsu[0] =~ /\d\d\d\d\.(\d\d)\.\d\d/
month = $1
else
raise "日時の表記が不正です:#{line}"
end
sums[month] += hairetsu[1].to_i
end
end
}
sums.sort_by{|pair| pair[0].to_i}.each do |month, sum|
puts "#{target_year}年#{month}月の支出額 #{sum.to_s.rjust(6)} 円"
sougaku += sum
end

puts "------------------------------------------"
puts "#{target_year}年の支出総額 #{sougaku} 円"
0361デフォルトの名無しさん2011/03/07(月) 21:23:32.37
余談だけど、Ruby1.9が速いってのは嘘だから
「速くする事もできる」が正確
普通なスクリプトを普通に作ったら、1.8よりも遅い
0362デフォルトの名無しさん2011/03/07(月) 21:29:15.80
RubyをCに変換するソフト知りませんか?
0363デフォルトの名無しさん2011/03/07(月) 21:33:15.10
>>361
全ての文字列がエンコーディング情報つき文字列になったのに、それで速くなるわけないじゃん
0364デフォルトの名無しさん2011/03/07(月) 21:50:22.48
>>361
>「速くする事もできる」が正確
詳しく
0365デフォルトの名無しさん2011/03/07(月) 21:50:35.01
http://anlyznews.blogspot.com/2011/02/objective-c.html
これ見たらどうみても1.9のほうが早いみたいだが・・・?
0366デフォルトの名無しさん2011/03/07(月) 22:02:27.44
>>360は1.9.2のほうが遅いなあ
0367デフォルトの名無しさん2011/03/07(月) 22:08:08.66
>>365
Rubyにはマイクロベンチマークのセットがあるので、
外部からよくわからんソースを引っ張ってくる必要はない

http://jp.rubyist.net/magazine/?0025-Ruby19_Performance
http://jp.rubyist.net/magazine/?0025-TheGreatRubyShootout
http://programmingzen.com/2010/07/19/the-great-ruby-shootout-july-2010/

1.9ではメソッドディスパッチとかの基本的な足回り部分は高速化されているが
文字列関係の処理はM17Nの関係で遅くなることがある
また、大部分がCで記述されているという点に変化はないので、
実アプリでの高速化はせいぜい数割程度
03683552011/03/07(月) 22:13:12.35
>>360さん
改良ありがとうございました。これは1.9以降用になりますね?
自分にとって "01" => 0 と sort_by, pair というものが新しい概念ですが、
調べて身に付くようにしたいと思います。

$ time /usr/local/bin/ruby suitou_2ch_360.rb 2000
real 0m0.741s
user 0m0.470s
sys 0m0.090s

ブレはありますが、おおむね 0.8秒以内(5倍増し!)で計算が完了するように
なりました。1.6.8 よりも早くなってる〜。
これでこのマシンをまだまだ使ってやれます。


>>361さん
アルゴリズムを勉強した方が良いということですね?がんばってみます。
0369デフォルトの名無しさん2011/03/08(火) 01:39:10.61
railsからruby始めますって人には
rails installerがいいの?

rubyのホームページには、バイナリを使う場合は
mswin版とmingw版の違いはないって書いてあるけど
実際のとこどうなの?

xpにはmswin、7にはmingwってのはガセ?
0370デフォルトの名無しさん2011/03/08(火) 08:14:04.25
WindowsでUTF8だかUNICODEだかのファイル名やテキストを
操作するスクリプト書きたいんですが
どのバイナリだと可能でどのバイナリだと不可能みたいのってあるんですか?
-KuというのをつけておけばどれでもOK?
0371デフォルトの名無しさん2011/03/08(火) 08:19:09.66
>>369
Railsやるって人はRailsスレに行ったほうが的確なアドバイスがもらえるかと思う
ttp://hibari.2ch.net/test/read.cgi/php/1292032736/
一般論として、Rubyインストール後にgem install railsでRails一式と自分に必要なものをインストールするのは
若干の知識と根性がいる
オールインワンなモノが自分にあったもの全部用意してくれるなら、それに頼ったほうがいんでないかね

mswinとmingwには動作的違いはないことになってるのだが、
「名前は違うけど動作おんなじ」というシステムのことをrubygemsが考えてくれなかったので、
mingwが一般認知される前に作られた古いバイナリつきgemライブラリが時々mingwを弾く、対処は>>345

>>5にもあるんだけど、稀に躓いてもいい(回復できる)のならmingwのほうがいいと思う、なにより新しいw
Ruby学習中に本質でないトラブルがジェットストリームアタックなので、手一杯な初心者には勧めない

>>370
Unicodeファイル名は扱えない(若干の語弊あり)
UTF-8で書かれたテキストファイルの内容は扱える
0372デフォルトの名無しさん2011/03/08(火) 08:55:23.19
>Unicodeファイル名は扱えない(若干の語弊あり)

内部はA系のAPI固定ってことなんですかね。
Ruby.NET(Iron Ruby?)も軽く調べつつ
とりあえずPowerShellでやることにします。

ありがとうございます。
0373デフォルトの名無しさん2011/03/08(火) 09:41:33.07
>>354 壊れてて自力じゃどうしようもできないこともありえるナイトリービルドを提供するのが
「親切」だと思うような危篤な人はあなたぐらいです。
0374デフォルトの名無しさん2011/03/08(火) 11:34:08.56
ここまでの流れからすると1.8だとUTF-8を扱えないからWebサイト作るときはSJISかEUCしか使えないって事ですか?
基本的にHTMLはUTF-8でやりたいので厳しいですね
0375デフォルトの名無しさん2011/03/08(火) 13:34:01.97
何かの入力を元にランダムな文字列を作成する場合は
Digest::SHA1などのハッシュ関数を使うと思うのですが、

入力元データが無く、単純にランダムな文字列を作成したい場合は
ハッシュ関数を使う必要は無いでしょうか?
0~1とa~zをランダムで選んで適当な数だけくっつければOKですか?

具体的にはユーザーから送られてくる画像に対して、出来る限りダブらないような任意のunique_idを振りたいのです。

よろしくお願い致します。
03763752011/03/08(火) 13:39:30.10
すいません、付け足しです。
自分で調べた限り、SecureRandomというモジュールで安全なランダム文字列を作れるとのことですが、
入力元データが無い以上、
0~1とa~zをランダムで選択してくっつける方法よりもセキュアにランダム文字列作る方法があるとは思えないのですが
この考え方は間違ってるのでしょうか。
0377デフォルトの名無しさん2011/03/08(火) 13:49:12.46
画像に振るIDにセキュアとか関係ないと思うが
連番が一番信頼できるIDなのだが、連番じゃダメなのか?
03783752011/03/08(火) 13:55:23.44
セキュアの意味は、同じ文字列を生成しないという意味だと思っていたのですが、違うのですか?

連番にできれば一番効率もいいと思うのですが、仕様でランダム文字列で管理するように決まっていまして
下っ端PGの自分には意見する権利が無いのです。
0379デフォルトの名無しさん2011/03/08(火) 14:10:12.42
まあ、あれだ、
http://example.com/upload/012.jpg があったら 011.jpg や 013.jpg を探されるけど
http://example.com/upload/d3id9f.jpg があったら「前」や「次」のファイルを探そうとは思わない

というセキュリティばっちりの、お前んちのパソコンは加減乗除しかできない電卓かなにかかという仕様なのだろう
0380デフォルトの名無しさん2011/03/08(火) 14:26:37.98
>>376
SecureRandomはシステムからアクセス可能な最大レベルの乱数発生器を使用してランダム数列を作る
というかむしろ、そういうのが入手不可能だった場合は実行できずに例外出して死ぬ
自前で「らんだむにする」なんてのよりもよっぽど偏りがないぞ

ただ、既存との被りチェック機能はないので、それのチェックは自力でやる必要あり
過去と被る可能性がかなり低いというだけで、絶対被らないというわけではない
100まんこのデータIDが溜まってしまった場合、作ったIDが過去と被らないかのチェックは100まん回行う必要がある

これのコストを許すことができない場合は>>377の言うように素直に連番にする
これは少なくとも絶対に被らないから、被りチェックのコストはゼロだ
0381デフォルトの名無しさん2011/03/08(火) 14:27:03.60
>>378
セキュアは「安全」という意味で、
大体こういう場合は「セキュリティ的に問題がない」みたいな意味。
ネットの辞書で調べられるでしょ。

ランダム文字列がいいなら、
現在時間のTimeオブジェクトにランダム数値の文字列をくっつけてハッシュとか、
かっこつけたければsaltとして真ん中に適当な文字列を入れ込むとか。
まあなんでもいいと思うよ。

>>379
ああ、エロ画像の一括ダウンロードとかか
0382デフォルトの名無しさん2011/03/08(火) 14:33:46.81
>>378
「セキュアな」というのは、
悪意のあるユーザーが乱数の規則性を発見しようとしても困難だという意味
単に衝突を回避したいというのであれば、
乱数を元に十分なだけ文字列を並べればいい

そうすると乱数の種が問題だが、まあ現在時刻とかでもいいかもね
あんまり厳密なことを求めてないようだし
0383デフォルトの名無しさん2011/03/08(火) 14:40:49.54
>>380
コリジョンについてのはどうなんだろうね
そのへん脅すとたいてい連番でいいよって言ってくれるもんなんだが

いや、衝突なんてまず起きないけどさ…
0384デフォルトの名無しさん2011/03/08(火) 14:46:59.77
ひとえに「万一衝突が起きたらどうなるか」によるな
地球が爆発しますとかなら連番にしておいたほうが無難
過去のファイルが上書きされて公開されますとかなら菓子折りでも持って謝りに行っとけ
0385デフォルトの名無しさん2011/03/08(火) 14:51:40.10
Rubyに向いてない処理ってどういうのですか?
0386デフォルトの名無しさん2011/03/08(火) 15:07:20.31
Ruby 関係ないけど、連番+乱数みたいなフォーマットにすればコリジョンは発生しないのでは?
03873752011/03/08(火) 15:25:19.08
皆様ありがとうございます。
しかし乱数発生器という概念がやはりよく分かりません。。

たとえば以下のようにランダム文字列を作った場合、

source = ('a'..'z').to_a + (0..9).to_a
a = Array.new(10){source[rand(source.size)]}
a.join

同じくa~zと0~9を用いてこれよりランダムな10桁の文字列を作るのは不可能ではないですか?
全ての桁で何にも依存せずにランダムに文字を決めているのだからこれ以上分散させようが無いと思うのですが。
推測もしようがないと思います。
0388デフォルトの名無しさん2011/03/08(火) 15:35:53.77
連番というか、日付をプラスするというのはよく見るね
/upload/20110308/a8b3c7f382.jpg
これなら万一の場合の被害範囲も小さいので説得も簡単だろう
その日のディレクトリ内のファイルなんて多くて1万とかだろ(適当)
「本日のディレクトリ内にファイルが既に存在したら再抽選」という処理でも間に合うはず

まあ、そんな小細工しなくても、結果の文字列がじゅうぶんに長ければ衝突の心配はほぼない
正確を期すと「衝突しないわけではありません」と答えるしかないのが大変辛いところではあるが

Ruby関係ないな
0389デフォルトの名無しさん2011/03/08(火) 15:45:08.83
>>385
Rubyで実行して1秒以上かかるような処理は本質的に向いてない
まるちめでぃあとか数値計算とかGUIぐりぐりとかあのへんは苦手分野だ
一般的なゲームも、他の言語と比べた場合はあんまり得意とは言えない
頑張ればなんとかならなくもないのだが、「敢えてRubyでやることに意義がある」という状態なので、
結果が欲しいだけという一般なピーポー様は素直に他の言語で作ろうPythonとかどうすかPython

>>387
その rand() の精度が問題
たとえば、100万回を3回実行したけど毎回1が100個ほど多い、とかだと困る
乱数の種として oasjfoiefdasifj を与えると 4829384 番目の7文字目に同じ数字が出るとか
100万回の結果をプロファイリングすると乱数の種の4文字目は34パーセントの確率で1だとか
普段の使用ではこんなの気にするのは基地外レベルだが、乱数発生器としては失格

SecureRandom.hex とかが重宝されているのは、ランダム数字から16進数を導き出す計算に偏りがないため
rand() で被る確率と SecureRandom で被る確率そのものは、前者のほうがはるかに高いはず
SecureRandom 相当が自由に使用できるなら、乱数発生に SecureRandom を使用しない理由は何もないと思うよ
0390デフォルトの名無しさん2011/03/08(火) 16:38:47.31
被らない乱数製造機

ransuu = 1..1000000000.to_a.sort_by{|x| rand}

ransuu.pop
03913752011/03/08(火) 16:48:22.61
うーむ、とても難しいですね(汗)
今の自分にはちょっと理解できないですが、頂いたレスをもう一度じっくり読んでみます。
ありがとうございました。
0392デフォルトの名無しさん2011/03/08(火) 16:51:40.85
だから何も言わず SecureRandom 使え
天文学的確率でしか被りませんと胸を張れる
rand() は一意になる ID のようなものを作るのにはもともと向いてないのだ
0393デフォルトの名無しさん2011/03/08(火) 17:03:18.87
>>375
> 具体的にはユーザーから送られてくる画像に対して、出来る限りダブらないような任意のunique_idを振りたいのです。

1) スレッドセーフにシーケンスな整数を割り振り
2) 受付時間を整数にして使う

2ちゃんのdatなんかは後者でファイル名つけてるね。
03943932011/03/08(火) 17:04:24.51
あ、スレ読めてなかったスマソ…。忘れて…。
0395デフォルトの名無しさん2011/03/08(火) 18:35:34.34
>>372
1.9.2ならunicodeファイル名扱えるよ
0396デフォルトの名無しさん2011/03/08(火) 18:37:26.00
>>376
入力元データがないなら、乱数を使ってデータを作ればいい。
require 'digest/sha1'
seed = [rand(), rand(), rand(), rand(), Time.now.to_f].pack('ddddd')
p Digest::SHA256.hexdigest(seed)

ところでhexdigest()は0-9a-fまでの16文字を使うけど、これを0-9a-zまでの文字を
使うようにすれば、同じ情報量でも生成される文字列は短くできるよね。
0-9a-zまでなら36文字か。0-9a-zA-Zと'-'と'_'を使えば、64文字。
hexdigest()のかわりに、バイト列をこの64文字を使って表現する方法を
だれか教えてください。

0397デフォルトの名無しさん2011/03/08(火) 18:56:10.67
近いところで
SecureRandom.base64(32)
=> "97LXeNU4g2xG75E0qmvX0+kI34zJkw1+fh/XvJAvEOY="
0398デフォルトの名無しさん2011/03/08(火) 19:12:31.88
>>397
できれば任意のバイナリを受け取る方法が知りたい。
0399デフォルトの名無しさん2011/03/08(火) 19:58:08.87
>>398
ヒント:
 0と1の2文字しか使わない2進数
 0から7の8文字しか使わない8進数
 0から9の10文字しか使わない10進数
 0からfの16文字しか使わない16進数
 0から_までの64文字しか使わないのは
0400デフォルトの名無しさん2011/03/08(火) 20:02:17.95
ハッシュはキーがシンボルなら key:val って書けるじゃん
で値もシンボルなら key: :val ってなって見た目ががっかりなんだが
ここらへん開発陣に問題意識はある感じですかね?
0401デフォルトの名無しさん2011/03/08(火) 20:06:28.18
追いかけてないが、特になかったと思った
値もシンボルというのはそういうの的には稀だし
0402デフォルトの名無しさん2011/03/08(火) 20:08:27.01
Pythonを覚える場合はRuby覚える必要ってないですか?
0403デフォルトの名無しさん2011/03/08(火) 20:09:56.77
ない
0404デフォルトの名無しさん2011/03/08(火) 20:12:46.15
>>398
バイナリを6ビットずつに区切って、使いたい文字に割り当てればよろしい。
0405デフォルトの名無しさん2011/03/08(火) 20:14:43.65
つまりBASE64と
0406デフォルトの名無しさん2011/03/08(火) 20:38:07.26
そうですか。今日ちょうどそういうのがあったので
dir=Dir.glob '*.*'.encode Encoding::UTF_8
dir.each{|e| puts e.encode Encoding::WINDOWS_31J, undef: :replace, invalid: :replace, replace: '?'}
0407デフォルトの名無しさん2011/03/08(火) 21:05:05.66
>>404
それをやってくれる便利なメソッドかライブラリがないでしょうか。
0408デフォルトの名無しさん2011/03/08(火) 21:13:05.22
base64
0409デフォルトの名無しさん2011/03/08(火) 21:35:08.75
[SecureRandom.hex(16)].pack("H*")
0410デフォルトの名無しさん2011/03/08(火) 21:38:12.40
あーすまん。よく読んでなかった
0411デフォルトの名無しさん2011/03/09(水) 01:19:25.20
>>400
先日IRCでちょっと話題になったな
問題意識がないわけじゃないがノーアイディア
0412デフォルトの名無しさん2011/03/09(水) 10:07:55.18
劣化って程じゃないんだね
安心してPS3版買えるよ
教えてくれてありがとう
0413デフォルトの名無しさん2011/03/09(水) 11:54:14.36
どういたしまして
0414デフォルトの名無しさん2011/03/09(水) 12:42:49.62
>>411
というかJSON互換なんだから値は数値と文字列しか想定してないだろ
0415デフォルトの名無しさん2011/03/09(水) 13:05:56.75
>>414
JSON互換ならキーはクォートされた文字列でなければならない。
YAML互換と言うべきだろう。
0416デフォルトの名無しさん2011/03/09(水) 13:34:21.60
>>415
YAMLの仕様にはシンボルなんてない。
もしシンボルが使えたら、それはSyck独自拡張。
0417デフォルトの名無しさん2011/03/09(水) 13:34:51.73
てか所詮リテラルレベルで互換性語ってもかなり滑稽だ
「どっかから○○形式の記述をコピペしてここで使える」という以上の意義をまったく見出せない
0418デフォルトの名無しさん2011/03/09(水) 13:41:15.96
そうだ!
:key => :value
って表記法はどうかな?
0419デフォルトの名無しさん2011/03/09(水) 13:44:30.84
>>414-416の展開がそのまんま答だなw
みんなして「○○記述形式でよくある、なんかコロンで繋ぐやつ」という認識でしかねえw
だから実際に何形式なのかを言葉にするとガンガンすれ違う

解釈後に生成されるオブジェクトからして、Ruby引数オリジナルと考えるのが一番真っ当だと思う
0420デフォルトの名無しさん2011/03/09(水) 14:16:22.94
たぶんPythonのキーワード引数の踏襲。
0421デフォルトの名無しさん2011/03/09(水) 16:24:50.31
引数以外でも使えるよ
{kew: 'value'} => {:kew=>"value"}
0422デフォルトの名無しさん2011/03/09(水) 16:31:03.59
>>420
Matzの趣味的にはCommon Lispだろう
0423デフォルトの名無しさん2011/03/09(水) 22:32:49.71
Ruby1.9.2でWindowsのUnicodeテキストファイル UTF-16LE(改行:<CR+LF>)+BOM を
読み書きするにはどうしたらよろしいのでしょうか?

abc<CR+LF>
を読むとバイト列が [255, 254, 97, 0, 98, 0, 99, 0, 13, 0, 10]
となってLFの2バイト目が分断されているようです

それとBOMの適切な処理方法があれば教えてください。
(設定によってBOMを読み飛ばしてくれたりバイトオーダーを設定できたりする機能があれば)

ソース
# coding: utf-8

$stdin.binmode
#$stdout.binmode

$stdin.set_encoding 'utf-16le'
$stdout.set_encoding 'utf-16le'

while row = gets
p row.each_byte.to_a #=> [255, 254, 97, 0, 98, 0, 99, 0, 13, 0, 10]
print '#', row
end


printのところでエラー
xxxx.rb:11:in `write': incomplete "\n" on UTF-16LE (Encoding::InvalidByteSequenceError)
0424デフォルトの名無しさん2011/03/09(水) 23:01:22.09
>>423
質問の一部にだけしか回答できないけど

> LFの2バイト目が分断されているようです
getsのline separatorが10 00ではなく10になっているとかじゃないか
0425デフォルトの名無しさん2011/03/09(水) 23:09:47.00
getsって意外とめんどくさいよね
0426デフォルトの名無しさん2011/03/09(水) 23:13:59.29
>>423
gets のあとで tell すると 11 と返ってきたけど、これって
次に読むのが最後の1バイト(00)っていう状態かしら。
0427デフォルトの名無しさん2011/03/09(水) 23:17:23.08
getsは使うときドキドキするね

$stdin.binmodeを外すとどうなるだろう
0428デフォルトの名無しさん2011/03/09(水) 23:19:50.29
gets は $/ を区切りとするんだけど、これがそのままだと 0x10 なので、
$/ = "¥r¥n".encode('UTF-16LE') としたらうまくいった。
BOMをむしるところまでは出来ないけど。

>>427
binmode は ascii-incompatible なエンコーディングを読むときに必要だと
怒られる。

0429デフォルトの名無しさん2011/03/09(水) 23:41:14.14
>>428
なるほど。やってみた

`set_encoding': ASCII incompatible encoding needs binmode (ArgumentError)

テキスト読むのにbinmodeにしろとか気持ち悪いね
BOM, $/ともども手当てしてあってもおかしくないんだけど
0430デフォルトの名無しさん2011/03/10(木) 00:03:48.58
NoMethodError: undefined method `to_utf8' for "\343\201\277\343\201\213\343\202\223":String
(#^ω^)ピキピキ
0431デフォルトの名無しさん2011/03/10(木) 00:07:24.88
(::゚∀゚::) そんなにピキピキしてないで俺でも食えよ
0432デフォルトの名無しさん2011/03/10(木) 00:07:52.94
$/ をケアするとして、こいつはあいにく特定のIOに結びついたものでは
ないので、やるとすれば、getsが毎回その時点での $/ を対象IOの
エンコーディングに合わせて変換することになるんだろうな。

IOインスタンスごとに line_delimiter みたいなプロパティを用意して、
デフォルトがそれになるようにするのがよいのかもしれん。
あれ、ないんだっけ…?

0433デフォルトの名無しさん2011/03/10(木) 00:12:40.29
getsはデリミタとして使用する文字列を引数にとるだろ
まったく試してないが gets("\r\n".encode('UTF-16LE')) でいけるはずだ
あと>>428はマカー
0434デフォルトの名無しさん2011/03/10(木) 00:38:45.19
WebKit通すとバックスラッシュが yen になっちまうからばれるんだよね…
04354232011/03/10(木) 00:51:17.63
改行の読み込みはデリミタ指定でうまくいきました。ありがとうございました。
BOMはとりあえず見てみぬふりをします。

# coding: utf-8

$stdin.binmode # バイナリモードでないとエラー :in `set_encoding': ASCII incompatible encoding needs binmode (ArgumentError)
# $stdout.binmode # バイナリモードだと改行が<LF>

$stdin.set_encoding 'utf-16le'
$stdout.set_encoding 'utf-16le'

while row = gets("\r\n".encode('utf-16le'))
p row.each_byte.to_a #=> [255, 254, 97, 0, 98, 0, 99, 0, 13, 0, 10, 0]
 print '#', row.chomp, "\n" # <CRCRLF>対策
end
0436デフォルトの名無しさん2011/03/10(木) 01:08:58.29
BOMについてはまともに対応しようとすると大変らしいので(よくわからない)、
とりあえず$stdinを2バイトseekしてから使い始めとけばいいんじゃないかな。
0437デフォルトの名無しさん2011/03/10(木) 01:15:35.90
なにその誤爆するまで前進
0438デフォルトの名無しさん2011/03/10(木) 07:52:45.66
IO#getsだとちゃんと改行を読むね
open('hoge','rb:UTF-16LE') do |io|
while row = io.gets
p row.each_byte.to_a #=> [255, 254, 97, 0, 98, 0, 99, 0, 13, 0, 10, 0]
end
end
p $/ #=> "\n"

Kernel#getsの不具合なのかな
0439デフォルトの名無しさん2011/03/10(木) 08:07:06.44
それと、Ruby1.9.2だとBOM判別、読み飛ばし機能が付いてた
open('hoge','rb:BOM|UTF-16BE') do |io|
while row = io.gets
p row.each_byte.to_a #=> [ 97, 0, 98, 0, 99, 0, 13, 0, 10, 0]
p row.encoding #=> #<Encoding:UTF-16LE>
end
end

openのモード指定でexternal-encodingがUTF系のときBOM|をつけると
BOMを判別してエンコーディング決定&BOM読み飛ばし
BOMがなければ指定されたエンコーディングに

1.9でIOのクラスメソッドが ハッシュ引数をとるようになったので
IO.foreach('hoge',mode:'rb:BOM|UTF-16LE'){|row| p row.each_byte.to_a}
とかできる
でも
IO.foreach('hoge',binmode:true, external_encoding:'BOM|UTF-16LE')
みたいな external_encodingでの指定は効かなかった
対応し忘れ?
例によってドキュメントないけどorz
0440デフォルトの名無しさん2011/03/10(木) 08:26:13.93
> mode:'rb:BOM|UTF-16LE'

やっぱこの記法キモいわ
あ、でも1.9専用って示すのにはいいかも
0441デフォルトの名無しさん2011/03/10(木) 18:19:42.88
>>438-439
ほう……俺が考え付くようなことは既に実装されてるんだね

>>440
一瞬新しいハッシュの記法かと思った
0442デフォルトの名無しさん2011/03/11(金) 07:46:49.98
>>441
新しいハッシュの記法だと思ってた。
ハッシュじゃないならmode:の部分がベアワードでエラーになりそうな気がするから。
0443デフォルトの名無しさん2011/03/11(金) 14:13:43.92
Ruby初心者を脱した自覚くらいはあって、
これからかっこいい中級者になりたいなと思ってるんだけど、
そのために必要なぷろぐらみんぐちしきとかを勉強できる本とかないもんですかね
っていうか足りない知識ってなんだろう
0444デフォルトの名無しさん2011/03/11(金) 14:18:06.57
デザインパターンとかリファクタリングとかあのへんの本を読むと、今なら面白いかも
あとソフトウェアテスト関係
Webに関連する生活をしてるならHTTPのRFCとか

他人のライブラリソースを読むのもいいけれどね
0445デフォルトの名無しさん2011/03/11(金) 14:27:16.65
配列内の要素をソートしたいのですが、方法が分かりません。

具体的には、scoreというインスタンス変数を持ったBookクラスがあり、
このBookクラスのオブジェクトの配列book_listがあるとします。
book_list内のBookオブジェクトをscoreの高い順に並び替えたいのですが、
自分で考える限り、以下のような感じで力尽きます。

sorted_book_list = []
book_list.each do |b|
sorted_book_list.each_with_index do |sb, i|
if b.score > sb.score
# i番以降の要素を全て一つ後ろにずらす処理がここで必要だが実現できたとしてもパフォーマンスが酷そう。
sorted_book_list[i] = b
break
end
end
end

もっとスマートな方法があれば教えて頂けないでしょうか。
0446デフォルトの名無しさん2011/03/11(金) 15:00:13.72
sorted_book_list = book_list.sort {|a, b| a.score <=> b.score }
0447デフォルトの名無しさん2011/03/11(金) 15:34:37.78
Perlだとハッシュテーブルの配列の大きさを

keys %hash = 64;

と指定できるのですが、Rubyにもそういう機能はありますでしょうか?
0448デフォルトの名無しさん2011/03/11(金) 15:37:39.50
>>445
book_list.sort_by {|book| book.score }

>>447
残念ながらない
■ このスレッドは過去ログ倉庫に格納されています