Ruby 初心者スレッド ..
369:デフォルトの名無しさん
08/01/29 02:36:32
>>368
(p(i%1)).class と解釈されるからじゃなかろうか
370:デフォルトの名無しさん
08/01/29 02:39:59
なるほどこれならうまくいきました
irb(main):004:0> (0..1).each{|i| p((i%2).class) }
Fixnum
Fixnum
=> 0..1
371:デフォルトの名無しさん
08/01/29 15:38:23
正規表現を合理化するスクリプトを書いているのですが,
以下のようにつらつらと書くと,とても手間が掛かるので,
もっと簡単に行う方法はないのでしょうか?
$KCODE="SJIS"
str = '2007年(01|02|03|04|05|06|07|08|09|10|11|12))月'
str.gsub!('(01|02|03|04|05|06|07|08|09|10|11|12)','(0[1-9]|1[0-2])')
str.gsub!('01|02|03|04|05|06|07|08|09','0[1-9]')
str.gsub!('10|11|12|13|14|15|16|17|18|19','1\d')
str.gsub!('20|21|22|23|24|25|26|27|28|29','2\d')
str.gsub!('30|31|32|33|34|35|36|37|38|39','3\d')
str.gsub!('40|41|42|43|44|45|46|47|48|49','4\d')
str.gsub!('50|51|52|53|54|55|56|57|58|59','5\d')
str.gsub!('60|61|62|63|64|65|66|67|68|69','6\d')
str.gsub!('70|71|72|73|74|75|76|77|78|79','7\d')
str.gsub!('80|81|82|83|84|85|86|87|88|89','8\d')
str.gsub!('90|91|92|93|94|95|96|97|98|99','9\d')
str.gsub!('10|11|12','1[0-2]')
p str
372:デフォルトの名無しさん
08/01/29 15:51:38
もう死ぬしかないね
373:デフォルトの名無しさん
08/01/29 16:22:31
ああ.一応4行目で変換は完了してるんですが,
strの中身が以下の様だったりする場合にも対応したいので.
str = '2007年(01|02|03|04|05|06|07|08|09|10|11)月' => 2007年(0[1-9]|1[01])月
str = '2007年(10|11|12)月' => 2007年1[0-2]月
str = '(2007年(10|11|12)月|2008年(01|02|03|04|05|06|07|08|09|10|11|12)月)' => (2007年1[0-2]月|2009年(0[1-9]|1[0-2])月)
str = '01|02|03|04|05|06|07|08' => 0[1-8]
str = '11|12|13|14|25|26|27|28' => 1[1-4]|2[5-8]
といった感じに変換されるようなモジュールなどはありませんか?
374:デフォルトの名無しさん
08/01/29 16:22:59
>>371
まず何がしたいのか分からん
375:デフォルトの名無しさん
08/01/29 16:31:41
長い正規表現を短くまとめたいのですが.
376:デフォルトの名無しさん
08/01/29 16:37:29
>>374
>>373だろ
要は、/1|2|3|4|5/ を /[1-5]/ に変換するようなうまい方法はないか、という質問
変換用のペアを自前で記述したものを作って総置換かける以外の方法はないような気がする
Rangeオブジェクトを使うと '11|12|13|14|15|16|17|18|19' を (11..19).to_a.join('|') にできるがその程度だろう
377:デフォルトの名無しさん
08/01/29 16:41:23
>>376
そうですか.ゴリゴリ書いてみます.
ありがとうございました.
378:デフォルトの名無しさん
08/01/29 16:42:58
???
そもそも正規表現ってなんだっけ?と考えてしまったろぉ
379:デフォルトの名無しさん
08/01/29 16:45:00
>>377
外部から正規表現を受け取って短く変換して返すというアプリケーションを作ってるなら、わりと無駄だと思うのでやめとけ
正規表現の記述が短くなったからといって正規表現としての効率が上がるとは限らない
冗長に記述したほうが速いぜということもままあるはず
で、もし、既に存在する正規表現を手作業でくっつけてるために変換を欲してるのなら、
Regexp.joinで正規表現をくっつけることも検討するといい
380:デフォルトの名無しさん
08/01/29 16:47:43
URLリンク(eroero.com)
を
URLリンク(eroero.com)
URLリンク(eroero.com)
URLリンク(eroero.com)
URLリンク(eroero.com)
URLリンク(eroero.com)
展開するのってどうやるの?
381:デフォルトの名無しさん
08/01/29 16:53:36
>>380
自動ではできないと思う
自分で都合のいいマッチ条件を書いて場合分けして置換するしかないんじゃね
与えられた文字列で{数字A-数字B}を検知したら数字Aから数字Bまでのeachを起動してその部分を数字に置換する、とか
zshなんかでは専用の処理が既に組み込まれてたりしたはず
382:デフォルトの名無しさん
08/01/29 16:56:30
正規表現の最適化とかそういうことをやるには、正規表現処理系の中身に
手を出すような処理が必要になる、つまり自分で正規表現処理系を新しく
実装して、とかいうことになる。
383:デフォルトの名無しさん
08/01/29 17:04:13
後に画期的なコンパイラコンパイラを生み出す371であった
384:デフォルトの名無しさん
08/01/29 17:06:03
URLリンク(eroero.com)
のほうがいいんじゃまいか、そんで
URLリンク(eroero.com)
がいいな
385:デフォルトの名無しさん
08/01/29 17:06:40
eroero.comが普通に存在している件
386:デフォルトの名無しさん
08/01/29 17:08:42
どうでもいいが例示はexample.comを使え
実在するドメインに迷惑かけないように
387:デフォルトの名無しさん
08/01/29 17:09:34
>>379
ええ.ありがとうございます.
ただし,私の場合,スピードを求めているのではなくて,
可読性の向上と255文字制限を回避するためなのです.
255文字制限は他のプログラムで存在するので対策が必要です.
他のプログラムで,あるデータベースから自動的に生成された
年月日などの規則性のある,連続した数字の羅列を,
正規表現で表現し,さらに簡潔な表記に変換した後,
テキストで出力し,そのファイルを別のプログラムで使用する
という形のプログラムを作成中です.
ちょっと組んでみたのですが,かなり面倒ですねw
2桁の数字で真面目にやったら1000行超えちゃいますね.
ああ面倒だ.頻出の物だけで済ませるか.
数字を纏める事一つでここまで手こずるとは予想外でした.
388:デフォルトの名無しさん
08/01/29 17:49:12
>>387
要件が曖昧な気がするな。
例) 01, 02, 11, 13
これの要約表現として、
a) [0-1][1-3]
b) 0[1-2]|11|13
のどちらのようなものを求めるか、もわかりにくい。
数値としての範囲を記述させようという b)のようなら、正規表現は向かないだろう。
a)のように各桁独立で、0-9範囲の文字として処理させるなら、20行もいらないと思うが。
389:デフォルトの名無しさん
08/01/29 18:21:59
>>388
基本的には「元の正規表現と等価である」というのが要件です.
a)の場合は元の数値を含んでいますが,それ以外の
03や12なども含んでしまいますから等価ではないと思います.
そのあたりの厳密性が要求されるのでb)が望ましいと言えます.
思いついたアルゴリズムとしては,|で区切った数値を
全て配列に書き出して,ソートして,一つ一つ取り出して,
連続しているようなら[ - ]で繋ぐという様なアルゴリズムで
やろうかなと思います.
390:デフォルトの名無しさん
08/01/29 18:32:10
ふくろう本(みみずく本だっけ?)にないかなあ
とあてずっぽうを言ってみるテスト
391:238
08/01/29 19:45:54
大変な遅レスです。すみません。
>>255
うう、Cygwinは捨てたくないし、Winを捨てたら Win32OLEが使えませんし、ちょ
と困ります。その関数もさすがに煩雑ですし。
>>261
おお!この手があったか!ありがとうございます。さっそく読んでみます。
392:デフォルトの名無しさん
08/01/29 20:11:08
>>388
perlのRegexp::Assembleのソース読んでみれば。
393:デフォルトの名無しさん
08/01/29 20:20:28
>>389
単純なalternationだけでいいなら、
いったん全部をトライ木に突っ込むのが簡単。
394:デフォルトの名無しさん
08/01/29 21:29:58
>>392
perlですか.勉強してみます.
>>393
なるほど.トライ木ですか.
ありがとうございます.
395:デフォルトの名無しさん
08/01/29 21:39:06
というか、出力パターンが極めて限定されていて、
正規表現として解釈する必要が本質的に無いとかいうオチは無いだろうか
396:デフォルトの名無しさん
08/01/29 23:53:14
俺も正規表現使わないほうが早いんじゃないかとちょっとだけ思った
397:デフォルトの名無しさん
08/01/29 23:55:06
パイプで別のプログラムを呼ぶときのことで質問させてください。
Rubyはmswin32の1.8系です。
RubyからMeCab(形態素解析ツール)を呼ぼうと次のように書いたのですが、
関数内での結果受け取り部分をどう書くのがよいかわかりません。。
プロンプトでMeCabの動作は、上記のようにオプションなしに呼んだ場合、文字列の入力を促され、
入力すると複数行の結果とEOS(文字列)が返って、次の入力待ちになります。
私\t説明
の\t説明
名前\t説明
EOS
・・(入力待ち)
以下ではこの流れをそのまま書きました。(続く)
398:397続き
08/01/29 23:55:58
def parse(str)
result = []
io = open("|C:/MeCab/bin/mecab.exe", "r+")
io.puts str
#ここで解析結果受け取り(後述)
io.close; result
end
result_array = parse("私の名前") #結果を配列で受け取る
ここで、入力待ち状態になったところをRubyでどう受け取ってMeCabを終わらせたらいいのかわからないのです。
nilなどが返るわけじゃないみたいですし・・・
自分なりに書いたコードは以下で、一応動いています。(上記関数内のコメント部分に入る)
while 1
word = io.gets.chomp!
break if /\AEOS\z/ =~ word
result << word
end
io.puts "^C" #こんなわけないような・・・
EOSの行は不要なのでこうしたのですが、MeCab以外の場合のことを考えるとこれじゃダメですよね。
もっと一般的な書き方があったら、おしえてください。(入力待ちになったら終了、など)
399:デフォルトの名無しさん
08/01/30 00:02:55
>>397
一般論として、相手側がまだ出力を続けているけど遅延か何かでたまたまデータが来ないのか、はたまた出力が終わって今度は入力待ちになったのか、を知る方法はない。
今回の例だったら、EOSが来て相手の出力が終わったことはわかるんだから、もう用がないならio.closeでOK。
400:デフォルトの名無しさん
08/01/30 00:04:03
io.close_writeかな?
あと、回答とは違うがmecab-rubyを使うという選択肢はなし?
401:397
08/01/30 00:22:58
>>399 >>400
ありがとうございます。入力待ちで信号が来るわけじゃないんですね。
mecab-rubyはcygwin版でないとインストールが面倒そうだったので
早々にあきらめてしまいました。
過去スレにはWin32APIを介して・・というのも出ていたのですが
自分のスキルでは未知の領域なので同様に^^;
402:デフォルトの名無しさん
08/01/30 02:41:18
ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-cygwin] です。
まちがって終わらない Thread を作ってしまい、Cygwin を走らせている
アプリごと止めたんですが、改めて実行したら deadlock エラーがでました。
しかたがないので再起動してみたんですが、それでも deadlock がおきます。
ためしに irb を起動してみたらこのようにゾンビ化した Thread が残っています。
$ irb
irb(main):001:0> Thread.current
=> #<Thread:0x1003c978 run>
これ、どうやって消すんでしょうか?
403:デフォルトの名無しさん
08/01/30 03:05:51
>>402
それ単なる自分のスレッドだから。
アプリでdeadlockが起こってるってのはなんかロックとして使ってるファイルでも
消してないんじゃないか?tmpとか見てみれ
404:デフォルトの名無しさん
08/01/30 03:55:40
>>403
> それ単なる自分のスレッドだから。
そうみたいですね。 はやとちりでした。
どうやら自分が Thread の扱い方を理解していないだけみたいです。 orz
405:デフォルトの名無しさん
08/01/30 16:09:34
正規表現で前からずっと気になってたので質問。
「でっかいHTMLから<title>を抜き出す」という場合
html.scan(/<title>(.+?)<\/title>/)
みたいな書き方するんだけど、これよく考えたらhtml内で</title>が終わった後もえんえんサーチしてるよね。
「ひとつ見つけたらそこで終了させる」というような指定はできない?
406:デフォルトの名無しさん
08/01/30 16:17:57
>>405
'123451'.scan(/(1)/){p Time.now.to_f}
1201677254.19416
1201677254.19554
ということで、マッチするものが見つかるたびにブロックを実行してるようなので
'123451'.scan(/(1)/){ p $1; break}
"1"
即breakすれば桶
407:デフォルトの名無しさん
08/01/30 16:18:55
ブロック内でbreakすればいいんじゃない?
408:デフォルトの名無しさん
08/01/30 16:23:14
そもそもscanを使わないというのは無しですか?
p $1 if /<title>(.*?)<\/title>/ =~ html
409:デフォルトの名無しさん
08/01/30 17:08:38
html.scan(/<title>(.+?)<\/title>/, 1)
410:デフォルトの名無しさん
08/01/30 18:07:49
>>409
これなんだろうと思ってリファレンスマニュアル見たけど無いよ
slice(regexp[, nth]) の間違いだな
411:デフォルトの名無しさん
08/01/30 18:45:11
WinとLinux(LinuxZaurus)で動くシリアルポートを操作するツールを作りたいのですが
何か良い方法があったら教えてください
シリアルポート操作クラスはあるようですがWin用だったりして
WinとLinuxであまりコードを変えたくないのですが…
Winでmodeコマンド&IO.openを使う方法を試しているのですが
`MODE COM4 BAUD=115200 PARITY=N DATA=8 STOP=1`
com = open("COM1", 'r+b')
sleep(1)
com.syswrite("AT@K20\r")
sleep(0.1)
while true
$> << com.sysread(1)
end
com.close
よろしくお願いします
412:デフォルトの名無しさん
08/01/31 01:03:43
すみません、RDEで実行結果(コンソールウィンドウ)をUTF8Nで表示する方法教えて下さい。
いろいろ試したのですが文字化けが直りません。
(以前のPCでは表示された気がしたのですが設定方法忘れてしまいました)
RDE v1.1.1 / Ruby-mswin32 v1.8.6 / WindowsXP SP2
RDE設定
・フォント(設定&エディタ設定): MS Pゴシック、文字セット:日本語
・Ruby通常オプション: 「-Ku」(無しでも試したがダメ)
・コードウィンドウ>文字コード変換: japanese.dll(Y SJIS)にunicode.dllを追加(Y SJIS)
・コードウィンドウ>文字コード・ 「UTF8N + 改行:LF」
コード先頭に#!○○/ruby -Kuや$KCODE = 'u'、2行目に日本語のコメントを付けてもダメでした
文字コード変換のDLLのSJISを変更しないとダメなのでしょうか?(方法が判らないです)
413:デフォルトの名無しさん
08/01/31 15:20:33
Rubyから実行中のDirectXのfpsを取得するライブラリーとかない?
念を押すと、fpsのみでいいんだけども。
414:デフォルトの名無しさん
08/01/31 16:55:01
Rakefileで
CXX = 'g++'
CXXFLAGS = '-Wall -g'
TARGET = 'hellorake.exe'
SRCs = FileList['./*.cpp']
OBJs = SRCs.sub(/$/, '.o')
task :default => TARGET
class Rake::Task
alias :preqs :prerequisites
end
require 'rake/clean'
CLEAN.include(OBJs)
CLEAN.include(TARGET)
rule('.cpp.o' => [proc {|o| o.sub(/\.cpp\.o$/, '.cpp') }]) do |t|
sh "#{CXX} #{CXXFLAGS} -o #{t.name} -c #{t.source}"
end
file TARGET => OBJs do |t|
sh "#{CXX} -o #{t.name} #{t.preqs}"
end
だとうまくいくのですが
「rule('.cpp.o' => [proc {|o| o.sub(/\.cpp\.o$/, '.cpp') }]) do |t|」の部分をシンプルにしようと思い
「rule '.cpp.o' => '.cpp' do |t|」にしたらDon't know how to build task './hellorake.cpp.o'と言われてしまいます
Matzの呪いかと思ったのですがC言語なソースにしても同じでした><
415:デフォルトの名無しさん
08/01/31 18:20:10
>>413
> 実行中のDirectXのfpsを取得するライブラリーとかない?
うーん。見たことないな・・・
DirectXの録画ソフトだと大抵ついている機能だから、
作者に頼んでみるとか、
オープンソースのソースを見て自分で作るとか
416:415
08/01/31 18:27:34
>>413
試してないが、この辺とか
Taksi: Video capture/Screen capture for 3D applications
URLリンク(taksi.sourceforge.net)
他にも sourceforge に似たソフトがあったと思う
あと、ムービー録画するソフトに関してはこちらの方が詳しい
【鑑賞】 ムービースレッド 【作成】 part2
スレリンク(gamef板)
417:デフォルトの名無しさん
08/01/31 19:22:03
>>414
OBJs = SRCs.sub(/\.cpp$/, '.o')
rule '.o' => '.cpp' do |t|
なら動くが、二重のsuffixには対応しないんじゃね?
418:デフォルトの名無しさん
08/01/31 19:50:08
ていうか勝手に自己解釈で縮めんなよ
419:デフォルトの名無しさん
08/01/31 19:51:22
>>418 ???
420:デフォルトの名無しさん
08/01/31 20:37:42
教えてください。
UTF8の文字列に対して、正規表現で何かする場合に、
「〜」という文字が使えない気がするのですが、何故でしょうか?
Ruby1.8.6をWindowsで使ってます。
421:420
08/01/31 21:15:20
ごめんなさい。Kconvの問題のような感じなんですが。。
--------------------------
require 'kconv'
s = "〜あはははは〜"
if s =~ /〜.*〜/ then puts "Done"
else puts "Failed"
end
if s =~ /あ.*は/ then puts "Done"
else puts "Failed"
end
t = Kconv.tosjis(s)
u = Kconv.toutf8(t)
if u =~ /〜.*〜/ then puts "Done"
else puts "Failed"
end
if u =~ /あ.*は/ then puts "Done"
else puts "Failed"
end
----------------------
↑を実行すると
Done
Done
Failed
Done
となります。何か間違ってるところがあるのか、教えていただければ嬉しいです。
422:デフォルトの名無しさん
08/01/31 21:27:23
試さないで適当にレスするけど
正規表現の後ろにuってつけてみたらどうだ
/〜/u みたいに
423:デフォルトの名無しさん
08/01/31 21:30:10
>>421
文字コード指定してないんだから、そりゃマッチしなくて当然だ
初期状態では、正規表現はマルチバイト文字列にマッチしないようにできてる
(少なくとも確実にマッチするという保証はない)
$KCODEを設定するか、あるいは正規表現に文字コード指定をつけるかしないとダメ
424:デフォルトの名無しさん
08/01/31 21:34:09
「〜」であるべきコードの主力が
ウエーブダッシュ:〜
全角チルダ:~
のふたつあるのが問題かなーとおもったけど、ちがうのか
425:420
08/01/31 21:44:01
>>422
今、やってみましたが、変化無かったです。
>>423
頭に、$KODE指定も付けてみましたが、変化無かったです。
426:420
08/01/31 21:47:28
>>424
それは全く知りませんでした。
今、後半の「〜」をウエーブダッシュというので、書き換えて
やったらうまくいきました!!
本当に有難うございます。
ちなみにこの話っていうのはよく知られた問題なのでしょうか?
427:デフォルトの名無しさん
08/01/31 21:49:29
>>425
1. どんな$KCODE指定をつけたのか書くこと
2. tosjis&toutfで、正しく文字コードを変換できているかどうかをチェックすること
428:デフォルトの名無しさん
08/01/31 21:52:10
あーubuntuで作った文書をWinに持ってきたら
〜のつもりだった部分が全部ウェーブダッシュだったとかよくあるよな
429:420
08/01/31 22:03:02
>>427
1. $KCODE='UTF-8'としました。
コードのファイルはUTF-8で保存してます。
2. チェックの仕方が良く分からないので、ソースの文字コード指定で
以下のようにしましたが、変化無かったです。
t = Kconv.kconv(s, Kconv::SJIS, Kconv::UTF8)
u = Kconv.kconv(t, Kconv::UTF8, Kconv::SJIS)
>>428
そうなんですか!よくある問題なんですね。。勉強になります。
ホント有難うございました。こんな早くに解決するとは、、
422さん,423さんもありがとうございました。
430:デフォルトの名無しさん
08/01/31 22:06:40
〜は Mac ←→ Windows でも変になることがある厄介者。
431:デフォルトの名無しさん
08/01/31 22:10:02
WAVE DASH 問題 でググるとあれこれ出てくるぐらい有名な問題です
432:420
08/01/31 22:16:09
>>430 >>431
まじすか。ウエーブダッシュというものの存在自体しりませんでしたorz
初心者スレで質問してよかった。。
433:デフォルトの名無しさん
08/01/31 22:42:26
MSが〜を全角チルダで変換するのは1992年のWindows3.1登場から。
で、規格は〜をウェーブダッシュにしろといってるが、これは1994年製。
だから、互換性重視するWindowsで〜をUnicodeにするとみんな全角チルダになる。
規格通り変換テーブルを実装すると〜の変換先はウェーブダッシュになるから大変な目に
Unicodeの絡みであと問題になりやすいのは、MACがファイル名をNFDして持ち出してくることかな
434:86
08/01/31 23:33:29
すいません。未だにできないので、どなたかご教授ください。
文字列の距離を求めることはできるのですが、
母音(aiueo)の挿入、置換、削除が行われたときのみ、重みを1じゃなくて2としてで距離を計算したいんです。
kasaとsasaの距離は1
kasaとkasuの距離は2
といった感じです。どなたかよろしくお願いします。
435:デフォルトの名無しさん
08/02/01 00:08:29
def kyori(s, t)
s.split('').zip(t.split('')).inject(0){|x,y| y[0] == y[1] ? x : x += (y[0] =~ /[aiueo]/ ? 2 : 1) }
end
kyori('kasa', 'sasa')
=> 1
kyori('kasa', 'kasu')
=> 2
436:デフォルトの名無しさん
08/02/01 00:37:55
>>433
良く知らんけど、1992年にすでにCP932->Unicodeの変換表とかまであったの?
kernel32.dll に MultiByteToWideChar とかのユニコード変換系APIが
追加されたのは NT3.1以降、95以降らしい。
それ以前に互換性が問題になるほど外部に公開されてたAPIとか変換表ってあったん?
437:デフォルトの名無しさん
08/02/01 00:40:19
>>436
もちつけ。
438:デフォルトの名無しさん
08/02/01 01:19:06
WAVE DASH 問題の歴史は、安岡先生の
URLリンク(slashdot.jp)
とかかな
439:デフォルトの名無しさん
08/02/01 05:37:10
本に載っているとおりに実行しているのですができません。
file = open("test.txt")
print file.read
:in `initialize': No such file or directory - test.txt (Errno::ENOENT)
in `open'
と表示されます。
どなたか教えてください。
440:デフォルトの名無しさん
08/02/01 05:42:36
>>439
そのままの意味。
test.txtがないから開けない。
441:デフォルトの名無しさん
08/02/01 06:35:57
>>440
返答ありがとうございます。
test.txt があることは何度も確認しているのですが、
どうしても、エラー表示がでるので、他のファイルで試してみます。
442:デフォルトの名無しさん
08/02/01 06:46:11
おそらくファイルのせいではありません。
カレントディレクトリ、というものを意識してください。
443:デフォルトの名無しさん
08/02/01 07:34:53
またあれかな
'デスクトップ'
の文字コードが違うとか
444:デフォルトの名無しさん
08/02/01 08:43:40
>>442
>>443
ありがとうございます。
保存する前に実行していたので、エラーが出たようでした。
保存後実行で解決しました。
445:86
08/02/01 11:08:20
>>435
ありがとうございます。確かに距離はでましたが、
例えばyとyyyyの距離は挿入が3回行われるため距離3にしたいのです。
またuとyyyyなら距離4にしたいのです。
すいません、仕様不足でしたが、修正ソースお願いできないでしょうか?
446:86
08/02/01 11:13:37
追加ですが、比較に使用する文字列長は最低2でした。すいません。
なのでyuとyayaなら距離は5となります。
日本語からローマ字に変換したもの同士を比較してるのですが、もし母音が一文字なのが余計でしたら
例えば変換規則をxaなどとして必ず偶数番目に母音を入れることも可能です。
きゃとかしゃも何とかします。
447:デフォルトの名無しさん
08/02/01 11:31:53
Rubyを学ぶ気はなさそうだな
格好よく書かなければいけないという縛りを勝手に感じることがあるがそんなもん無視しろ
望む結果を出すプログラムであることが第一だ
448:デフォルトの名無しさん
08/02/01 11:35:21
どうがんばっても泥臭くしか書けないものも、無くはないからな
449:デフォルトの名無しさん
08/02/01 11:46:39
俺はよりよい(あるいはまともな)プログラムにするのは半年後の自分に任せてる
何かよくわからない素晴らしいメソッドを使って1行で書けるのかもしれないが、今自力で作ることのほうが重要
まあ、半年後にはRubyどころかプログラミング言語すら使ってないっていうパターンもあるだろうけどな
そういう場合は自己探求に任せるのは双方にとって馬鹿らしくはある
450:86
08/02/01 13:28:59
すいません。泥臭くてもやってみたいのですが、いかんせん>>435の
s.split('').zip(t.split('')).inject(0){|x,y| y[0] == y[1] ? x : x += (y[0] =~ /[aiueo]/ ? 2 : 1) }
という一文が何をしているのかよくわからなくって・・・
動作はするのに理解できてないのがわからず、修正しようにもできないのが現状です。
ですので、もしよかったらこの一文もご教授ください。。。ググッてみましたが.zipがうまく探せないです。
451:デフォルトの名無しさん
08/02/01 13:39:13
このスレにはタチの悪いオナニーワンライナーが生息してるからな
初心者に自分の技術(と信じてるもの)を見せびらかして悦に浸る人種
452:デフォルトの名無しさん
08/02/01 13:46:29
思考をifとeachとローカル変数にバラすのもめんどいっちゃめんどいけどな
意図的に書いてる奴は放置として、気づいた人が平易なほうに書き直すのがよいかと思われ
453:デフォルトの名無しさん
08/02/01 13:59:12
s.split('').zip(t.split('')).inject(0){|x,y| y[0] == y[1] ? x : x += (y[0] =~ /[aiueo]/ ? 2 : 1) }
とりあえず脊髄反射的にバラしてみる
s_splitted = s.split('')
t_splitted = t.split('')
zipped = s_splitted.zip(t_splitted)
zipped.inject(0){|x,y|
y[0] == if y[1] then
x
else
x += if y[0] =~ /[aiueo]/ then
2
else
1
end
end
}
split URLリンク(www.ruby-lang.org)
zip URLリンク(www.ruby-lang.org)
inject URLリンク(www.ruby-lang.org)
454:デフォルトの名無しさん
08/02/01 14:36:46
元のソース読むの面倒だったから、Wikipedia読んで一から書いた
class String
def levenstein(other)
return nil if self.empty?
return nil if other.empty?
# 距離行列のサイズを確定
row_size = self.size + 1
col_size = other.size + 1
dm = []
row_size.times do
dm << Array.new(col_size)
end
# 距離行列の値を初期化
for row in 0...row_size
dm[row][0] = row
end
for col in 0...col_size
dm[0][col] = col
end
(↓に続く)
455:デフォルトの名無しさん
08/02/01 14:37:36
(続き)
# 距離の計算
for row in 1...row_size
for col in 1...col_size
c1 = self.slice(row - 1, 1)
c2 = other.slice(col - 1, 1)
if c1 == c2 then
cost = 0
elsif c1 =~ /[aiueo]/ then
cost = 2
else
cost = 1
end
dm[row][col] = [
dm[row - 1][col] + 1, # 挿入
dm[row][col - 1] + 1, # 削除
dm[row - 1][col - 1] + cost # 置換
].min
end
end
#行列の最後の値が文字列間のレーベンシュタイン距離となる
return dm.last.last
end
end
puts 'kasa'.levenstein('sasa') #=> 1
puts 'kasa'.levenstein('kasu') #=> 2
puts 'yu'.levenstein('yaya') #=> 4
456:454
08/02/01 14:41:23
挿入コストやら削除コストやらは面倒だったんで全部1にした
あとは自分で何とかしてくれ
もしコードの内容にミスがあったら、誰か突っ込んでほしい
457:86
08/02/01 18:54:01
>>453
ありがとうございます。ソースまでのっけてくださって。
本来ならここで後は組み合わせろとなるところを
>>454
おかげで助かりました。
ただ、例えばauとyauuの距離が2になってしまうのでちょこっと改造しておきます。
if c1 == c2 then
cost = 0
elsif c1 =~ /[aiueo]/ then
cost = 2
else
cost = 1
end
のへんをいじってやってみます。
>>451から>>456にいたるまで、皆さん本当にどうもありがとうございました。
458:86
08/02/01 19:05:37
>>454
今見てやってみたら一瞬で改造できました。笑
ほんとにこんな長いソースを実ソースも見ずにやっていただいてありがとうございます。
僕も、もうちょっと勉強して、僕みたいな香具師を助ける側になれるようがんばります。
459:デフォルトの名無しさん
08/02/01 20:00:08
>>450
すまんそれはネタというか冷やかしで書いたもので
挿入とか削除とかに対応してないから使えないだろうな、とは思ってた。
勿論、技術をひけらかすつもりもない。
というか俺も素人だからそんなに大したコードじゃないと思うんだが・・・
zipは二つの配列からペア配列を作るメソッド
a=[:a,:b,:c]
b=[1,2,3]
c=a.zip(b) #=> [[:a,1],[:b,2],[:c,3]]
ハッシュ作るときとかにたまに使う
Hash[*c.flatten] #=> {:a=>1, :b=>2, :c=>3}
460:デフォルトの名無しさん
08/02/02 00:54:44
rubyにはawkやperlみたいな「一行野郎」集ってないの?
テキスト処理にわざわざスクリプト書きたくないんだけど。
461:デフォルトの名無しさん
08/02/02 01:01:47
こういうことを言うとおまえらから総攻撃を受けるかもしれないが
一行で書きたいならawk使ったほうがいいような気がする
462:デフォルトの名無しさん
08/02/02 01:14:45
awkの$1、$2に相当する組み込み変数はないの?
463:デフォルトの名無しさん
08/02/02 01:26:22
>>460
ここにいますよー。
Rubyの宿題スレにもそこそこいる
464:デフォルトの名無しさん
08/02/02 01:27:19
>>462
正規表現使った時にそいつら使えるぜ
465:デフォルトの名無しさん
08/02/02 01:27:59
ネタにマジレスで申し訳ないけど、「一行野郎」って人じゃなくてコマンドね。
466:デフォルトの名無しさん
08/02/02 01:31:20
>462
-aオプション(とゆーことは、-nか-pオプションも)付けたときだけだが
$F[0]、$F[1]、……が$1、$2……相当。
$0は$_
リファレンスのコマンドラインオプションのとこ参照
ちなみにそこ読めば書いてあるが$_をフィールドセパレータで分割したのが$Fなんで$FはArray
467:デフォルトの名無しさん
08/02/02 01:32:30
ワンライナーで書くための努力は、はっきしいって無駄な努力だよ。
ワンライナーでかけたからといって、自己満足でしかない。
468:デフォルトの名無しさん
08/02/02 01:32:33
perlのawkサポートと同じオプションだな。
469:デフォルトの名無しさん
08/02/02 01:32:40
File.open('hoge.txt').each { |line| puts(line.split.join('-')) }
みたいに書こうと思えば書けるが、
Perl みたいな変態的な省略は_
470:デフォルトの名無しさん
08/02/02 01:37:02
>>466
それだ。ありがと。
フィールドセパレータはどうやって設定するんだろう。。
>>467
君ってあまりコマンドラインシェル使ったこと無いでしょ。
471:デフォルトの名無しさん
08/02/02 01:38:25
>>470
いや、トテモトテモ使ってるよ。
472:デフォルトの名無しさん
08/02/02 01:41:12
FSは「$;」で、RSは「$/」だね。これなら使えそうだ。
473:デフォルトの名無しさん
08/02/02 01:45:30
BEGINとENDもあるな。
474:デフォルトの名無しさん
08/02/02 01:47:35
awk互換モードが欲しいな。2.0くらいでつけてほしい。
475:デフォルトの名無しさん
08/02/02 01:53:22
それはawkでいいじゃんw
476:デフォルトの名無しさん
08/02/02 02:08:31
awk的使い方でも、rubyの機能を使いたくならない?
477:デフォルトの名無しさん
08/02/02 03:02:51
windowsのコマンドプロンプトのコマンドラインで「|」を使えないから、one linerでブロックで変数を受け取る構文が書けないよ。
どうすればいいの?
478:デフォルトの名無しさん
08/02/02 03:21:41
>>477
普通に書けるけど?
> ruby -Ks -e "Dir.glob('*'){|x|p x}"
479:デフォルトの名無しさん
08/02/02 08:06:42
^でエスケープ
> ruby -Ks -e "Dir.glob('*'){^|x^|p x}"
480:86
08/02/02 10:00:40
>>459
ありがとうございます。zipに関してかなり理解できました。
けっこー使えそうなメソッドなのでばりばり使っていきます。
481:デフォルトの名無しさん
08/02/02 10:04:11
>>478
>>479
せんくす
482:デフォルトの名無しさん
08/02/02 13:43:33
ネット上の、時々更新されるHTMLをパースしてハッシュにして返すメソッドを作りました。
しかし、「データがありません」という場合どうするかで悩んでます。
a) 空のハッシュ {} を返す
b) 偽である nil を返す
c) 自作の例外を発生させる
どれが妥当でしょか。
このハッシュは別の大きなハッシュに {サイト名 => parsed_hash} のように格納される予定です。
データがありませんの大きな理由として
「過去のハッシュとの差分がゼロ」
「HTML中にパースすべき該当項目なし」
「そもそもサーバにアクセスできない」
等があります。
483:デフォルトの名無しさん
08/02/02 14:05:59
erbについて質問があります。
下記のようなコードを書いてerbに変数ItemListの内容を出力しようと思います。
PHPのテンプレートエンジンのSmartyのようにassignメソッドがあればいいのですが
どうも見当たりません。
変数のスコープの問題だと思うのですが、どうやって出力すればいいのでしょうか?
def initialize
@cgi=CGI.new
end
# 商品一覧
def doItemList
@erb = ERB.new("item_list.tpl")
im=ItemManager.new()
itemList=im.getItemList(10)
display()
end
# テンプレート出力
def display(contentType="text/html")
print "Content-Type: #{contentType}\n\n"
print @erb.result(binding)
end
484:デフォルトの名無しさん
08/02/02 14:49:15
Rubyが面白そうなので今日からRubyをはじめます(^-^)
まずはダウンロードしてこなきゃ!!o(^-^)o
485:デフォルトの名無しさん
08/02/02 14:54:20
>>460
俺がよく書くのは
> ruby -e "puts ENV['PATH'].split(';')"(sortを加えることも)
だって、生のPATH記述って読み辛いんだもの…。
486:デフォルトの名無しさん
08/02/02 15:00:05
>>459
なんだかすごく助けられた気がする
深謝
487:デフォルトの名無しさん
08/02/02 15:09:33
>>483
erbを一度も使ったことのない俺がWeb上の解説を読んで適当に回答するよ!
> in `display': undefined local variable or method `itemList' for #<MyCGI:0x4030ed9c> (NameError)
こんなエラーが出るという質問だと推測。itemListをインスタンス変数あたりに書き変えると動いたよ!
require 'erb'
class MyCGI
def doItemList
im = ItemManager.new
@itemList = im.getItemList(10)
@erb = ERB.new(DATA.read)
display
end
def display(contentType="text/html")
@contentType = contentType
@erb.run(binding)
end
end
class ItemManager
def getItemList(n); (1..n).to_a; end
end
MyCGI.new.doItemList
__END__
Content-Type: <%= @contentType+"\n\n" %>
<%= @itemList.join(',') %>
488:デフォルトの名無しさん
08/02/02 15:17:35
@erb.runあるいは@erb.resultをするメソッドから
erbスクリプト内で使ってる名前の変数が読めないとダメっぽいという話。たぶん。
だからこれでも動く。displayに引数があるのは気持ち悪いのでoutputに変更(というかdisplayはto_sの以下略)
require 'erb'
class MyCGI
def doItemList
im=ItemManager.new
itemList=im.getItemList(10)
@erb = ERB.new(DATA.read)
output(itemList)
end
def output(itemList, contentType='text/html')
@erb.run(binding)
end
end
class ItemManager
def getItemList(n); (1..n).to_a; end
end
MyCGI.new.doItemList
__END__
Content-Type: <%= contentType+"\n\n" %>
<%= itemList.join(',') %>
489:デフォルトの名無しさん
08/02/02 15:17:35
>>487
レスどうもです。
やっぱり、スコープの問題なんですね。
MyCGIのインスタンス変数にしてしまうってのが・・・
なんか書き方として気持ち悪いような。
itemListのまま使いたいとすれば、def doItemListの中でerbを使うしかないって事ですかね?
やっぱり、assign欲しい・・・
490:デフォルトの名無しさん
08/02/02 15:54:52
assignだと何か便利なんですかね
あとerb使うときはERB::Utilでエスケープするようにしてくれえ
491:デフォルトの名無しさん
08/02/02 16:42:55
bindingはただの関数的メソッドなので、変数に入れてdisplayに渡せばいい
ただ、bindingしたあとにローカル変数を「追加」するのは面倒なので注意
この場合、display内でcontentTypeを設定してitem_list.tplで使用するのは面倒
# item_list.tpl
<%=h itemList.map{|e| "<#{e}>"}.join(' ') %>
# out.rb
require 'erb'
class MyCGI
include ERB::Util
def doItemList
@erb = ERB.new(File.open("item_list.tpl").read)
im=ItemManager.new()
itemList=im.getItemList(10)
binding_data = binding
display(binding_data)
end
def display(binding_data,contentType='text/html')
print "Content-Type: #{contentType}\n\n"
print @erb.result(binding_data)
end
end
class ItemManager
def getItemList(n) ['あ','い','う','え','お']; end
end
MyCGI.new.doItemList
492:デフォルトの名無しさん
08/02/02 17:14:24
>>482
ハッシュを加工するなら空のハッシュを返すかも
HTMLから抜き出すならnilでいいんじゃね
493:デフォルトの名無しさん
08/02/02 17:30:02
>>490
assignあると明示的にこれ使いますよってできるから、わかりやすいんですよ。個人的には。
Railsだと、erbのスコープはどうなってるんでしょう?
494:デフォルトの名無しさん
08/02/02 17:48:35
引数バージョンをことごとく無視してるのは何か理由があるのか
いっそのことPHPで書けば?
495:デフォルトの名無しさん
08/02/02 19:35:17
引数バージョンって何?
496:デフォルトの名無しさん
08/02/02 19:41:33
bindingをdisplayの引数にすれば? ということじゃないの?
497:デフォルトの名無しさん
08/02/02 19:43:30
>>482
>ネット上の、時々更新されるHTMLをパースしてハッシュにして返すメソッドを作りました。
>しかし、「データがありません」という場合どうするかで悩んでます。
>
>a) 空のハッシュ {} を返す
>b) 偽である nil を返す
>c) 自作の例外を発生させる
「データがありません」を表すなら、b) がよい。
a) は、データがない場合とある場合とを同じように扱いたい場合に採用する設計。
c) はやりすぎ。
ただ、b)とa)はそう大差がない。
498:デフォルトの名無しさん
08/02/02 19:55:28
>>489
>やっぱり、assign欲しい・・・
あんま関係ないけど、Erubisだとできるみたい。assignじゃなくてHashつかうんだけど。
def doItemList
@eruby = Erubis::Eruby.new(DATA.read)
itemList = ItemManager.new.getItemList(10)
output(:itemList=>itemList)
end
def output(hash)
print @eruby.evaluate(hash)
end
>>490
>あとerb使うときはERB::Utilでエスケープするようにしてくれえ
これもErubis::EscapedEruby使うとデフォルトでエスケープされる。
499:デフォルトの名無しさん
08/02/02 20:23:12
>>496
>>488もじゃね?
表示したいデータをローカル変数にした状態でrunするので問題ないと思うんだけどなあ
変数の参照を全部持ってくbindingがイヤなんだろ、つまり
500:デフォルトの名無しさん
08/02/02 20:26:23
>>499
*.rhtmlでローカル変数を変更したら、それがもとのプログラムにも影響与えるじゃん。問題ありだろ。
501:デフォルトの名無しさん
08/02/02 20:48:21
require 'erb'
def main
include ERB::Util
erb = ERB.new(DATA.read)
str = 'strは文字列だよ!'
puts str
message = 'こんにちは'
print erb.result(binding)
puts str
end
main
__END__
<%=h message %>
<% str='strが変更されました' %>
=============================
~$ ruby erb.rb
strは文字列だよ!
こんにちは
strが変更されました
~$
ぬう
502:デフォルトの名無しさん
08/02/02 20:59:25
ページキャッシュ機能持ってるRubyのテンプレートエンジンってないの?
503:デフォルトの名無しさん
08/02/02 21:12:24
>>500-501
require 'erb'
class MyCGI
def main
str = 'default'
p str
msg1 = 'Hello'; msg2 = 'World'
output(msg1, msg2)
p str
end
def output(msg1, msg2)
erb = ERB.new(DATA.read)
erb.run(binding)
end
end
MyCGI.new.main
__END__
<%= "#{msg1},#{msg2}!" %>
<% str='**CHANGED**' %>
- - - 8< - - - 8< - - - 8< - - - 8< - - - 8< - - -
$ ./test.rb
"default"
Hello,World!
"default"
504:デフォルトの名無しさん
08/02/02 21:33:11
そんなに気になるならErb.newしてrunするクラスを別途作れば?
っていうのがきっとErubisなんだろうな…
505:デフォルトの名無しさん
08/02/02 21:38:29
>>502
出力結果のHTMLをキャッシュするという話なら、それはテンプレートエンジンとは別に用意する機能だよ。
テンプレートエンジンに持たせる機能じゃない。
506:デフォルトの名無しさん
08/02/02 21:56:08
>>505
つSmarty
507:デフォルトの名無しさん
08/02/02 22:17:06
素のERBには無理だろうね
そこまでは気を遣ってないというかそれは自力でやれというか
…Erubisにはあるようなことが書いてあるなあ
URLリンク(www.kuwata-lab.com)
508:デフォルトの名無しさん
08/02/02 23:35:37
Erubisは高速なERBとして、開発されてて、
その高速化の手段の一つとして、キャッシュすることも挙げてたからな。
Preprocessing 何つー機能もあるくらいだし
509:デフォルトの名無しさん
08/02/02 23:38:54
別にERBは遅くないけどね
510:デフォルトの名無しさん
08/02/03 02:08:48
プログラムの中から、コンソール出力に行くはずのテキストオブジェクトを奪ってファイルに出力したいんだけど。。
より具体的にはTest::Unitを使いたいんだが、そのログをファイルにしたい。
ぱっとリファレンスを読んだ限りじゃそういう類の見つからないし、なんかいい方法ないですか。
もし複数いい方法があれば、それぞれの違いについて簡単な解説つきだととても助かる。
511:デフォルトの名無しさん
08/02/03 02:10:55
ruby unko.rb > benki.txt
512:デフォルトの名無しさん
08/02/03 02:21:20
はじめまして、ネットワークの初歩のコードを書いてみたのですが
def checkSite( address )
url = URI.parse(address)
res = Net::HTTP.start(url.host, url.port){|http|
http.head(url.path)
}
# HTTP_OKなら
if res.code == 200 then
p res['content-type']
else
p res['content-type']
puts "error : " + res.code.to_s
end
end
実行結果が
"text/html;charset=UTF-8"
error : 200
になります
res.code == 200なのにifでうまくひっかかりません
これは何を勘違いしているのかご指摘お願いしますm(__)m
513:デフォルトの名無しさん
08/02/03 02:25:00
"200"
514:デフォルトの名無しさん
08/02/03 02:27:07
>>512
こういうのは自分で実際にデータを表示して試行錯誤
require 'uri'
require 'net/http'
url = URI.parse('URLリンク(www.2ch.net)')
res = Net::HTTP.start(url.host, url.port){|http|
http.head(url.path)
}
p res.code
の実行結果
$ ./http.rb
"200"
つまりはそういうこと
515:デフォルトの名無しさん
08/02/03 02:29:21
if res.code == '200' then
ならOK
516:デフォルトの名無しさん
08/02/03 02:31:10
>>513
>>514
>>515
さっそくのお返事ありがとうございます、解決しました
res.codeは数値だと思い込んでいて(.to_sできるし)ハマっていました
517:デフォルトの名無しさん
08/02/03 02:46:58
'200'と書くよりはわかりやすい(かも)
require 'net/http'
Net::HTTP.version_1_2
uri = URI.parse('URLリンク(www.2ch.net)')
res = Net::HTTP.start(uri.host, uri.port){|http|
http.head(uri.path)
}
if res.code_type == Net::HTTPOK
p res
end
518:510
08/02/03 03:16:21
>>511
519:510
08/02/03 03:16:48
すまん…
>>511
520:510
08/02/03 03:21:00
すまん、二回も立て続けに書きかけで書き込んでしまった
>>511
えと、それが出来るのならそうしたんだ。
ただ、残念ながら、telnetが禁止されてるレンタルサーバー上で、念のためモジュールテストを行いたくて、
そいでそういうニーズが出てきてるんだよ。
だから、そうやってコマンドラインでリダイレクトできれば楽なんだけど、コマンドラインそのものが扱えないというわけ。
まぁもっとも、UnixもRubyも初心者なので、その回答で正しいのなら…もう少し説明してくれると助かる。
521:デフォルトの名無しさん
08/02/03 03:25:56
#!/usr/bin/ruby
system("ruby unko.rb > benki.txt")
522:510
08/02/03 03:34:55
当たり前でシンプル。
ありがとう。なるほど。
後は必要に応じて加工し放題だな。
523:デフォルトの名無しさん
08/02/03 03:39:09
Ruby的には出力先をねじ曲げるのが妥当
$stdout=File.open('output.txt','w')
$stderr=File.open('errors.txt','w')
puts 'テストだよん'
raise 'エラーだよん'
これ以降、puts や print の標準出力は$stdoutで指定したoutput.txtに、
例外とかのエラー出力は$stderrで指定したerrors.txtに書き込まれる
が、これは意外とめんどいんで、シェルのリダイレクト代わりに使うなら>>521で十二分かと
524:デフォルトの名無しさん
08/02/03 03:41:42
>>521 だとフォームとかの情報が伝わらないんじゃないかな?
標準入力の情報を渡す必要がありそう。
525:デフォルトの名無しさん
08/02/03 03:45:40
ユニットテストならフォームの情報は不要で
自分でデータ渡してるだろうから多分問題ないだろう。
526:デフォルトの名無しさん
08/02/03 04:28:14
>ただ、残念ながら、telnetが禁止されてるレンタルサーバー上で、念のためモジュールテストを行いたくて、
いまどきtelnetなんてどこでも禁止されてるだろ
527:デフォルトの名無しさん
08/02/03 04:31:17
ターミナル経由のログインのことだと解釈したけど
ファミコンとかゼロックスとかと同じような感じ
528:デフォルトの名無しさん
08/02/03 05:29:46
今時、telnetといって文字通り捉えるのははずかしいぞ
次ページ最新レス表示スレッドの検索類似スレ一覧話題のニュースおまかせリスト▼オプションを表示暇つぶし2ch
5374日前に更新/271 KB
担当:undef