Ruby 初心者スレッド Part 41
■ このスレッドは過去ログ倉庫に格納されています
0001京 ◆SsSSsSsSSs
2011/02/10(木) 13:47:51★注意★ 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そこまで大多数にエッジ追いかけてもらって意味のある大人気のソフトウェアじゃないしなあ
クライアントプログラムなら開発版バイナリ公開するのにも意義があるけど、スクリプト言語ではな…
ちなみに、ある程度のマシンスペックがあればRubyのコンパイルは現実的な時間で終わる
ナイトリーはアレだが、週1で更新して遊んで試すということは可能
バイナリ公開されてないだけで、自分用のを適宜開発最新版にしてる人はいるはず
「誰も日本語をpで表示して使ってなかったZEやっちゃったZE!」というエンバグの過去があるので、
ある程度知識のある人が開発版コンパイルして日常使用してもらうのは実はありがたい
ただ、初心者スレ向きの話じゃないなw
0349デフォルトの名無しさん
2011/03/07(月) 19:10:16.58人手が足りてないとか何とか
(まあ人手が足りてるオープンソースなんてあるのか知らんが)
0350デフォルトの名無しさん
2011/03/07(月) 19:24:21.82自力でビルドできる、とかは当然含まれてるので、ナイトリービルドのバイナリとか
あまり意味がない。
0351デフォルトの名無しさん
2011/03/07(月) 19:28:29.89VC++ 6あたりだっけか
0352デフォルトの名無しさん
2011/03/07(月) 19:29:20.36/opt 以下にインストールしちゃえという事で、自前コンパイルしてたけど、仮想環境内で
ものの5分くらいでコンパイルは終わってた気がする
0353デフォルトの名無しさん
2011/03/07(月) 19:31:46.98mswin32 を今から環境そろえて作るのはもう無理
今からやる人は mingw になると思う
コンパイル経験さえあれば怖くないので興味のある方はどうぞ
0354デフォルトの名無しさん
2011/03/07(月) 19:53:53.39最新版あげてくれたらいいのに
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 童貞
0356355
2011/03/07(月) 19:55:20.94$ 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,*
...
0357355
2011/03/07(月) 19:58:55.81#!/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"]
0358355
2011/03/07(月) 19:59:38.08open("#{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.18while 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「速くする事もできる」が正確
普通なスクリプトを普通に作ったら、1.8よりも遅い
0362デフォルトの名無しさん
2011/03/07(月) 21:29:15.800363デフォルトの名無しさん
2011/03/07(月) 21:33:15.10全ての文字列がエンコーディング情報つき文字列になったのに、それで速くなるわけないじゃん
0364デフォルトの名無しさん
2011/03/07(月) 21:50:22.48>「速くする事もできる」が正確
詳しく
0365デフォルトの名無しさん
2011/03/07(月) 21:50:35.01これ見たらどうみても1.9のほうが早いみたいだが・・・?
0366デフォルトの名無しさん
2011/03/07(月) 22:02:27.440367デフォルトの名無しさん
2011/03/07(月) 22:08:08.66Rubyにはマイクロベンチマークのセットがあるので、
外部からよくわからんソースを引っ張ってくる必要はない
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で記述されているという点に変化はないので、
実アプリでの高速化はせいぜい数割程度
0368355
2011/03/07(月) 22:13:12.35改良ありがとうございました。これは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.61rails installerがいいの?
rubyのホームページには、バイナリを使う場合は
mswin版とmingw版の違いはないって書いてあるけど
実際のとこどうなの?
xpにはmswin、7にはmingwってのはガセ?
0370デフォルトの名無しさん
2011/03/08(火) 08:14:04.25操作するスクリプト書きたいんですが
どのバイナリだと可能でどのバイナリだと不可能みたいのってあるんですか?
-KuというのをつけておけばどれでもOK?
0371デフォルトの名無しさん
2011/03/08(火) 08:19:09.66Railsやるって人は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内部はA系のAPI固定ってことなんですかね。
Ruby.NET(Iron Ruby?)も軽く調べつつ
とりあえずPowerShellでやることにします。
ありがとうございます。
0373デフォルトの名無しさん
2011/03/08(火) 09:41:33.07「親切」だと思うような危篤な人はあなたぐらいです。
0374デフォルトの名無しさん
2011/03/08(火) 11:34:08.56基本的にHTMLはUTF-8でやりたいので厳しいですね
0375デフォルトの名無しさん
2011/03/08(火) 13:34:01.97Digest::SHA1などのハッシュ関数を使うと思うのですが、
入力元データが無く、単純にランダムな文字列を作成したい場合は
ハッシュ関数を使う必要は無いでしょうか?
0~1とa~zをランダムで選んで適当な数だけくっつければOKですか?
具体的にはユーザーから送られてくる画像に対して、出来る限りダブらないような任意のunique_idを振りたいのです。
よろしくお願い致します。
0376375
2011/03/08(火) 13:39:30.10自分で調べた限り、SecureRandomというモジュールで安全なランダム文字列を作れるとのことですが、
入力元データが無い以上、
0~1とa~zをランダムで選択してくっつける方法よりもセキュアにランダム文字列作る方法があるとは思えないのですが
この考え方は間違ってるのでしょうか。
0377デフォルトの名無しさん
2011/03/08(火) 13:49:12.46連番が一番信頼できるIDなのだが、連番じゃダメなのか?
0378375
2011/03/08(火) 13:55:23.44連番にできれば一番効率もいいと思うのですが、仕様でランダム文字列で管理するように決まっていまして
下っ端PGの自分には意見する権利が無いのです。
0379デフォルトの名無しさん
2011/03/08(火) 14:10:12.42http://example.com/upload/012.jpg があったら 011.jpg や 013.jpg を探されるけど
http://example.com/upload/d3id9f.jpg があったら「前」や「次」のファイルを探そうとは思わない
というセキュリティばっちりの、お前んちのパソコンは加減乗除しかできない電卓かなにかかという仕様なのだろう
0380デフォルトの名無しさん
2011/03/08(火) 14:26:37.98SecureRandomはシステムからアクセス可能な最大レベルの乱数発生器を使用してランダム数列を作る
というかむしろ、そういうのが入手不可能だった場合は実行できずに例外出して死ぬ
自前で「らんだむにする」なんてのよりもよっぽど偏りがないぞ
ただ、既存との被りチェック機能はないので、それのチェックは自力でやる必要あり
過去と被る可能性がかなり低いというだけで、絶対被らないというわけではない
100まんこのデータIDが溜まってしまった場合、作ったIDが過去と被らないかのチェックは100まん回行う必要がある
これのコストを許すことができない場合は>>377の言うように素直に連番にする
これは少なくとも絶対に被らないから、被りチェックのコストはゼロだ
0381デフォルトの名無しさん
2011/03/08(火) 14:27:03.60セキュアは「安全」という意味で、
大体こういう場合は「セキュリティ的に問題がない」みたいな意味。
ネットの辞書で調べられるでしょ。
ランダム文字列がいいなら、
現在時間のTimeオブジェクトにランダム数値の文字列をくっつけてハッシュとか、
かっこつけたければsaltとして真ん中に適当な文字列を入れ込むとか。
まあなんでもいいと思うよ。
>>379
ああ、エロ画像の一括ダウンロードとかか
0382デフォルトの名無しさん
2011/03/08(火) 14:33:46.81「セキュアな」というのは、
悪意のあるユーザーが乱数の規則性を発見しようとしても困難だという意味
単に衝突を回避したいというのであれば、
乱数を元に十分なだけ文字列を並べればいい
そうすると乱数の種が問題だが、まあ現在時刻とかでもいいかもね
あんまり厳密なことを求めてないようだし
0383デフォルトの名無しさん
2011/03/08(火) 14:40:49.54コリジョンについてのはどうなんだろうね
そのへん脅すとたいてい連番でいいよって言ってくれるもんなんだが
いや、衝突なんてまず起きないけどさ…
0384デフォルトの名無しさん
2011/03/08(火) 14:46:59.77地球が爆発しますとかなら連番にしておいたほうが無難
過去のファイルが上書きされて公開されますとかなら菓子折りでも持って謝りに行っとけ
0385デフォルトの名無しさん
2011/03/08(火) 14:51:40.100386デフォルトの名無しさん
2011/03/08(火) 15:07:20.310387375
2011/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.83Rubyで実行して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.31ransuu = 1..1000000000.to_a.sort_by{|x| rand}
ransuu.pop
0391375
2011/03/08(火) 16:48:22.61今の自分にはちょっと理解できないですが、頂いたレスをもう一度じっくり読んでみます。
ありがとうございました。
0392デフォルトの名無しさん
2011/03/08(火) 16:51:40.85天文学的確率でしか被りませんと胸を張れる
rand() は一意になる ID のようなものを作るのにはもともと向いてないのだ
0393デフォルトの名無しさん
2011/03/08(火) 17:03:18.87> 具体的にはユーザーから送られてくる画像に対して、出来る限りダブらないような任意のunique_idを振りたいのです。
1) スレッドセーフにシーケンスな整数を割り振り
2) 受付時間を整数にして使う
2ちゃんのdatなんかは後者でファイル名つけてるね。
0394393
2011/03/08(火) 17:04:24.510395デフォルトの名無しさん
2011/03/08(火) 18:35:34.341.9.2ならunicodeファイル名扱えるよ
0396デフォルトの名無しさん
2011/03/08(火) 18:37:26.00入力元データがないなら、乱数を使ってデータを作ればいい。
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.67SecureRandom.base64(32)
=> "97LXeNU4g2xG75E0qmvX0+kI34zJkw1+fh/XvJAvEOY="
0398デフォルトの名無しさん
2011/03/08(火) 19:12:31.88できれば任意のバイナリを受け取る方法が知りたい。
0399デフォルトの名無しさん
2011/03/08(火) 19:58:08.87ヒント:
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 ってなって見た目ががっかりなんだが
ここらへん開発陣に問題意識はある感じですかね?
0401デフォルトの名無しさん
2011/03/08(火) 20:06:28.18値もシンボルというのはそういうの的には稀だし
0402デフォルトの名無しさん
2011/03/08(火) 20:08:27.010403デフォルトの名無しさん
2011/03/08(火) 20:09:56.770404デフォルトの名無しさん
2011/03/08(火) 20:12:46.15バイナリを6ビットずつに区切って、使いたい文字に割り当てればよろしい。
0405デフォルトの名無しさん
2011/03/08(火) 20:14:43.650406デフォルトの名無しさん
2011/03/08(火) 20:38:07.26dir=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それをやってくれる便利なメソッドかライブラリがないでしょうか。
0408デフォルトの名無しさん
2011/03/08(火) 21:13:05.220409デフォルトの名無しさん
2011/03/08(火) 21:35:08.750410デフォルトの名無しさん
2011/03/08(火) 21:38:12.400411デフォルトの名無しさん
2011/03/09(水) 01:19:25.20先日IRCでちょっと話題になったな
問題意識がないわけじゃないがノーアイディア
0412デフォルトの名無しさん
2011/03/09(水) 10:07:55.18安心してPS3版買えるよ
教えてくれてありがとう
0413デフォルトの名無しさん
2011/03/09(水) 11:54:14.360414デフォルトの名無しさん
2011/03/09(水) 12:42:49.62というかJSON互換なんだから値は数値と文字列しか想定してないだろ
0415デフォルトの名無しさん
2011/03/09(水) 13:05:56.75JSON互換ならキーはクォートされた文字列でなければならない。
YAML互換と言うべきだろう。
0416デフォルトの名無しさん
2011/03/09(水) 13:34:21.60YAMLの仕様にはシンボルなんてない。
もしシンボルが使えたら、それは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みんなして「○○記述形式でよくある、なんかコロンで繋ぐやつ」という認識でしかねえw
だから実際に何形式なのかを言葉にするとガンガンすれ違う
解釈後に生成されるオブジェクトからして、Ruby引数オリジナルと考えるのが一番真っ当だと思う
0420デフォルトの名無しさん
2011/03/09(水) 14:16:22.940421デフォルトの名無しさん
2011/03/09(水) 16:24:50.31{kew: 'value'} => {:kew=>"value"}
0422デフォルトの名無しさん
2011/03/09(水) 16:31:03.59Matzの趣味的にはCommon Lispだろう
0423デフォルトの名無しさん
2011/03/09(水) 22:32:49.71読み書きするにはどうしたらよろしいのでしょうか?
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質問の一部にだけしか回答できないけど
> LFの2バイト目が分断されているようです
getsのline separatorが10 00ではなく10になっているとかじゃないか
0425デフォルトの名無しさん
2011/03/09(水) 23:09:47.000426デフォルトの名無しさん
2011/03/09(水) 23:13:59.29gets のあとで tell すると 11 と返ってきたけど、これって
次に読むのが最後の1バイト(00)っていう状態かしら。
0427デフォルトの名無しさん
2011/03/09(水) 23:17:23.08$stdin.binmodeを外すとどうなるだろう
0428デフォルトの名無しさん
2011/03/09(水) 23:19:50.29$/ = "¥r¥n".encode('UTF-16LE') としたらうまくいった。
BOMをむしるところまでは出来ないけど。
>>427
binmode は ascii-incompatible なエンコーディングを読むときに必要だと
怒られる。
0429デフォルトの名無しさん
2011/03/09(水) 23:41:14.14なるほど。やってみた
`set_encoding': ASCII incompatible encoding needs binmode (ArgumentError)
テキスト読むのにbinmodeにしろとか気持ち悪いね
BOM, $/ともども手当てしてあってもおかしくないんだけど
0430デフォルトの名無しさん
2011/03/10(木) 00:03:48.58(#^ω^)ピキピキ
0431デフォルトの名無しさん
2011/03/10(木) 00:07:24.880432デフォルトの名無しさん
2011/03/10(木) 00:07:52.94ないので、やるとすれば、getsが毎回その時点での $/ を対象IOの
エンコーディングに合わせて変換することになるんだろうな。
IOインスタンスごとに line_delimiter みたいなプロパティを用意して、
デフォルトがそれになるようにするのがよいのかもしれん。
あれ、ないんだっけ…?
0433デフォルトの名無しさん
2011/03/10(木) 00:12:40.29まったく試してないが gets("\r\n".encode('UTF-16LE')) でいけるはずだ
あと>>428はマカー
0434デフォルトの名無しさん
2011/03/10(木) 00:38:45.190435423
2011/03/10(木) 00:51:17.63BOMはとりあえず見てみぬふりをします。
# 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とりあえず$stdinを2バイトseekしてから使い始めとけばいいんじゃないかな。
0437デフォルトの名無しさん
2011/03/10(木) 01:15:35.900438デフォルトの名無しさん
2011/03/10(木) 07:52:45.66open('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.44open('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やっぱこの記法キモいわ
あ、でも1.9専用って示すのにはいいかも
0441デフォルトの名無しさん
2011/03/10(木) 18:19:42.88ほう……俺が考え付くようなことは既に実装されてるんだね
>>440
一瞬新しいハッシュの記法かと思った
0442デフォルトの名無しさん
2011/03/11(金) 07:46:49.98新しいハッシュの記法だと思ってた。
ハッシュじゃないならmode:の部分がベアワードでエラーになりそうな気がするから。
0443デフォルトの名無しさん
2011/03/11(金) 14:13:43.92これからかっこいい中級者になりたいなと思ってるんだけど、
そのために必要なぷろぐらみんぐちしきとかを勉強できる本とかないもんですかね
っていうか足りない知識ってなんだろう
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.720447デフォルトの名無しさん
2011/03/11(金) 15:34:37.78keys %hash = 64;
と指定できるのですが、Rubyにもそういう機能はありますでしょうか?
0448デフォルトの名無しさん
2011/03/11(金) 15:37:39.50book_list.sort_by {|book| book.score }
>>447
残念ながらない
■ このスレッドは過去ログ倉庫に格納されています