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

Ruby初學者スレッド Part 9

レス数が950を超えています。1000を超えると書き込みができなくなります。
0001紅寶石2006/11/21(火) 08:33:42
まずはマニュアル

マニュアル
http://www.ruby-lang.org/ja/man/
Ruby FAQ
http://ruby-lang.org/ja/man/?cmd=view;name=Ruby+FAQ
逆引きRuby
http://www.namaraii.com/rubytips/
Ruby リファレンスマニュアルの Windows HTML Help版
http://elbereth-hp.hp.infoseek.co.jp/ruby.html
Rubyリファレンスマニュアル刷新計画
http://doc.loveruby.net/


前スレ
Ruby初心者スレッドPart8
http://pc8.2ch.net/test/read.cgi/tech/1159424939/

>>2-10
0856デフォルトの名無しさん2007/01/14(日) 08:34:21
>851
これはRangeオブジェクトじゃなくて条件文の範囲式。
http://www.ruby-lang.org/ja/man/?cmd=view;name=%B1%E9%BB%BB%BB%D2%BC%B0#a.c8.cf.b0.cf.bc.b0

ここでわかるように式2が真になるまでが条件だから、
i=0 1<=iでないので偽
i=1 1<=iが成立し、同時にi<2となり、結果自体は真
i=2 上で一周しているから1<=iを調べるとこれが真で、i<2が成立しないので結果は真
i=3 i<2が成立しないので真

となる。

範囲式のふつうの使い方は、
i = 0
while i < 4
print i if (i==1)..(i==2)
i += 1
end
とかかな。

でもまあ、ふつうはこういう書き方はしない方がいいです。
おれ、このスレの回答以外でこの書き方したことないよ。
0857デフォルトの名無しさん2007/01/14(日) 10:57:23
こんな文法があったのか。全然知らなかった。
0858デフォルトの名無しさん2007/01/14(日) 13:40:57
ifって結構意外な仕様持ってるよね
if /re/ とか書けるっけ?
0859デフォルトの名無しさん2007/01/14(日) 13:55:51
今ためしてみたけど書けないっぽい
(それ書いてもどうなるものでもなさそうだけど)
0860デフォルトの名無しさん2007/01/14(日) 13:59:17
ifだけ微妙に式解釈が異なるってちょっとキモいな・・・。BASICじゃあるまいし。
0861デフォルトの名無しさん2007/01/14(日) 14:08:03
$_がセットされてれば if /re/ は機能する
0862デフォルトの名無しさん2007/01/14(日) 14:21:33
>>856
これって、if 自身が状態を持っているようですね。ローカル変数のような。
そのため、以下のソースを実行すると、x=3,y=5と表示されることがあります。

x = 1
while x <= 4
y = 5
while y <= 9
b = y == 6
e = y == 8
printf "x=%d,y=%d\n", x, y if b..e
break if x==2 && y==6
y += 1
end
x += 1
end
0863デフォルトの名無しさん2007/01/14(日) 16:04:08
>850です。

>>856
式2は (i<2) ではなくて (2<i) です。

> ここでわかるように式2が真になるまでが条件だから、
式2が偽になった回でもその一回は結果として真になる、ということですよね。
そこで、 (2<i) の部分を (2<=i) にすれば意図どおりのタイミングで偽になるように
なるかと思って試しましたが、これも123と表示される結果となりました。

そこで856の「一周しているから」という文により気づいたのですが、式2が真となった
回の次回以降は、リファレンスにあるように偽になるのではなく、式1の評価に戻る、
ということですね。
そうなると、式2を(2<=i)と変更した場合に 3 が表示される理由も分かります。

ようやっと条件式としての範囲式の意味が理解できました。
856さん、他のみなさん、ありがとうごさいました。

>>862
その式の状態が、コード単位なのかメソッドの属するオブジェクト単位なのか
スレッド単位なのかメソッド呼び出し単位なのかよく分からんことから
範囲式について調べようと思った、というのがそもそもの動機なのですが、
 >856> でもまあ、ふつうはこういう書き方はしない方がいいです。
と言われているとおり、862をみると、「一周する」ということが確かな状況以外では
誰が読んでも意味不明なコードになるだろう、ということは分かりました。

もし純粋にif文単位で状態が保持されるのなら、例外で中断して再開した場合に
その式を評価した場合に状態が引き継がれたりするなどひどい泥沼になるように
思えるので、深入りせずここらで引き上げることにします。
0864デフォルトの名無しさん2007/01/14(日) 18:40:27
>>863
メソッド呼び出し単位。

状態を持っているのはifではなくて、flip-flop operatorで自動的に作られる
隠しローカル変数。
0865デフォルトの名無しさん2007/01/14(日) 20:19:46
>>864
864を見て試してみましたが、たしかにメソッド単位のローカル変数のようですね。
Proc.newやloopやtimesなどにブロックを渡してその中で範囲式を使ってみましたが、
ブロック内のローカル変数とは違って、状態は記憶されているようです。

ブロック付きopenをループやretryで複数回実行するときなどは注意が必要そうですね。
0866デフォルトの名無しさん2007/01/15(月) 11:47:08
flip-flip operatorって、awkやってた人くらいしか使わんのかな?
0867デフォルトの名無しさん2007/01/15(月) 13:08:37
>>866
awk/sed ではそれなりに使ったけど
perlやrubyでは使ったことない。
0868デフォルトの名無しさん2007/01/15(月) 16:45:53
Rubyのページが開かないのですが移転したのでしょうか?
http://www.ruby-lang.org/
0869デフォルトの名無しさん2007/01/15(月) 17:00:40
今なら開いたよ。
0870デフォルトの名無しさん2007/01/15(月) 17:08:38
あ、ほんとだ。
どもでした。
0871デフォルトの名無しさん2007/01/16(火) 02:59:10
unset var
みたいに、ローカル変数を取り消すことってできますか
0872デフォルトの名無しさん2007/01/16(火) 05:37:09
undef
0873デフォルトの名無しさん2007/01/16(火) 11:01:25
文字列の100から450文字を指定した文字に置き換えるにはどうすればいいのでしょうか?

str[100,350] = "g"
でやると、一文字しか置換されないのです。かといって"ggggg…"のように長くは間違いがでそうだし
何か簡単にする方法はありませんか?
0874デフォルトの名無しさん2007/01/16(火) 12:25:20
>"ggggg…"のように長くは間違いがでそうだし
Rubyでは同じ文字列のくり返しは乗算で実現できる。
"g"*350とか。
0875デフォルトの名無しさん2007/01/16(火) 12:26:40
"g" * 351 は?
0876デフォルトの名無しさん2007/01/16(火) 12:27:28
レス内容被った。スマソ
0877デフォルトの名無しさん2007/01/16(火) 12:58:22
>>871

nilを代入するのではダメでシンボルテーブルから変数名自体を消したいってこと?

>>872
undefはメソッドしか未定義にできないな。
これも厳密には未定義にするわけじゃなかったり。


0878デフォルトの名無しさん2007/01/16(火) 13:06:30
今度は、100から、350000000までを置き換えたいのですが
"g"*350000000とすると、メモリを300MBも消費しました。
なんとかする方法はないですか?
0879デフォルトの名無しさん2007/01/16(火) 13:22:11
ループでやれば?
0880デフォルトの名無しさん2007/01/16(火) 13:23:40
メモリを増築すればいいと思うよ。
0881デフォルトの名無しさん2007/01/16(火) 13:42:57
350000000.times {|i| str[i + 100] = 'g' }
0882デフォルトの名無しさん2007/01/16(火) 15:17:30
貧乏ならともかく300MBぐらいなら問題とは思えんが。
ループでやったって置換した結果の文字列のほうは結局大きくなるんだから変わらん気がす。
てっきり勉強目的で意味がないことをやってるんだと思ってたんだけど
なんか目的があるなら、それを言えばなんか考えてくれる人がいるかもよ。
特に意味はない話ならメモリを300MB使うことなどなんら問題じゃない。
0883デフォルトの名無しさん2007/01/16(火) 15:21:17
ネタじゃなかったのかwww・・・?
0884デフォルトの名無しさん2007/01/16(火) 15:45:25
g*35000000を代入する場合は、一時的に右辺のオブジェクトと代入後の
strの両方が存在するから1つずつ置き換えていくよりメモリは余計に必要。

だと思ったんだが、もしかしてRubyでは部分文字列は共有されてるのかい?
0885デフォルトの名無しさん2007/01/16(火) 17:31:36
つうか、本気だとして、こういうのは置換後の長大な文字列の使用用途にもよると思う
ファイルに保存するなら置換しながら…というか書き込みながら続ければいいわけだし
0886デフォルトの名無しさん2007/01/16(火) 18:00:15
str.fill("g",100..350)

>>885
それが一番の問題だと思う。初心者スレだからなおさらだな。
strに350MBもデータをコピーしてる時点でなんか間違ってる
可能性が大きいわけで、fillを使えば済む話じゃないかもしれん。
0887デフォルトの名無しさん2007/01/16(火) 19:32:58
質問したいのですが、ファイルの有無を判断するのにはどうしたらいいんでしょうか?
いろいろと調べてみたのですが、わからないのでどなたかわかる方がいらっしゃったらよろしくお願いします。
0888デフォルトの名無しさん2007/01/16(火) 19:33:50
FileTest
0889デフォルトの名無しさん2007/01/16(火) 20:44:30
>>887
フォルダをクリックして確かめる。
0890デフォルトの名無しさん2007/01/16(火) 21:23:56
>887
FileTest.exist?(filename)
filename が存在する時、真を返します。
0891デフォルトの名無しさん2007/01/17(水) 00:28:12
ITmedia エンタープライズ:まつもとゆきひろ――第3回:僕の存在価値はそこにある (1/4)
http://www.itmedia.co.jp/enterprise/articles/0701/15/news024.html

1回目と2回目のインタビューのリンクもあるので、Rubyファンはぜひ。
08928782007/01/17(水) 00:28:46
>>878はネタです。す、すまんw
0893デフォルトの名無しさん2007/01/17(水) 00:58:12
インスタンスメソッドをクラス定義の外でする方法は何かありますか?
クラスメソッドなら

class ClassA
・・・
end

def ClassA::method_b
・・・
end

のような形で書けるみたいですがインスタンスメソッドの場合がどうも見当たらないんです。
0894デフォルトの名無しさん2007/01/17(水) 01:27:57
>>893

ClassA.class_eval{
 def foo
  ・・・
 end
}
0895デフォルトの名無しさん2007/01/17(水) 01:39:51
>>894
できました。ありがとうございます。
0896デフォルトの名無しさん2007/01/17(水) 02:01:02
>>891
>プログラミング言語はすべて愛おしい


   ∩___∩         |
   | ノ\     ヽ        |
  /  ●゛  ● |        |
  | ∪  ( _●_) ミ       j
 彡、   |∪|   |        J
/     ∩ノ ⊃  ヽ
(  \ / _ノ |  |
.\ “  /__|  |
  \ /___ /
0897デフォルトの名無しさん2007/01/17(水) 02:21:12
>>886
> str.fill("g",100..350)
String#fillなんてあったっけ?
0898デフォルトの名無しさん2007/01/17(水) 02:35:38
>>897
fillはArrayだった。886は間違い。
0899デフォルトの名無しさん2007/01/17(水) 03:16:37
>>894
なんでこれが、クラスではなくインスタンスのメソッドになるのか
ちっとも理解できないのだけれど……。
分かりやすいサイトプリーズ
0900デフォルトの名無しさん2007/01/17(水) 03:20:07
>>899
リファレンスに書いてあるよ。
0901デフォルトの名無しさん2007/01/17(水) 03:23:46
>>899
わかりやすいサイトは思いつかないが、スコープの問題を除けば、

class ClassA
 # X
end

と、

ClassA.class_eval{
# Y
}

とでは、XとYは同じ環境になる。
単にそれだけ。
0902デフォルトの名無しさん2007/01/17(水) 03:34:38
すまん。インスタンスメソッドと、
特定のインスタンスだけに定義されたメソッドを混同していた。
さいきんruby使う暇なくて忘れてたorz
0903デフォルトの名無しさん2007/01/17(水) 07:00:53
>>877
>nilを代入するのではダメでシンボルテーブルから変数名自体を消したいってこと?

そうです。ERB用にこんなことをしたいんです。

# HashからBindingをつくる
def create_binding(_hash)
_defstr = _hash.inject('') { |_s, _e| _s << "#{_e[0]} = _hash[#{_e[0].inspect}];" }
eval _defstr
#undef _hash, _defstr # これができないものかと。
binding()
end

b = create_binding(:a=>10, :b=>'foo', :c=>%w[x y z])
0904デフォルトの名無しさん2007/01/17(水) 09:39:30
>>896
たしか Matz は I hate C++. と逝っていたと思うんだけど、
それでもいとおしいと思ってるんだね。
0905デフォルトの名無しさん2007/01/17(水) 09:41:29
嫌よ嫌よも好きのうち?
0906デフォルトの名無しさん2007/01/17(水) 10:01:30
>>903
むしろ一時変数なんか気にすんなって言いたいが。
そもそもevalした時点で安全でなくなっているわけだし。

ハッシュ受け取ってローカル変数なりクラス変数なりに展開するERBの子クラスを作ればいいんじゃないのか。
0907デフォルトの名無しさん2007/01/17(水) 11:25:02

流れ見ないで書き込むんだけど、evalとかで変数表を表示したときに
一時変数も一緒に出て来てしまうのが気に入らないとか?

0908デフォルトの名無しさん2007/01/17(水) 11:56:36
>>903
とりあえず現在のところローカル変数を明示的に消すことはできない
のでやりかたを変えるしかない。
0909デフォルトの名無しさん2007/01/17(水) 12:16:34
>>904
最近は本気で2chのデマを信じ込む奴が結構居るから、
これくらいのアッサリ風味でこられると本気なのか釣りなのか判断つかない。
0910デフォルトの名無しさん2007/01/17(水) 12:36:21
いるよな、デマだということにして火消しに必死な奴
関係者か?
0911デフォルトの名無しさん2007/01/17(水) 12:40:19
本人乙
0912デフォルトの名無しさん2007/01/17(水) 13:15:36
RHGの20.2.2によると、ruby-talkでmatzがそう発言したということらしいが、軽く探しても見当たらなかった。
0913デフォルトの名無しさん2007/01/17(水) 13:25:56
いつも大事にお使いいただきありがとうございます。
煽りあいは本スレでお願いいたします。
0914デフォルトの名無しさん2007/01/17(水) 23:18:09
Dir.globってなに?。自分でオープンすれば代替できるからいいんだけど。

irb(main):001:0> Dir.glob("c:/本/*")
=> []
irb(main):002:0> Dir.open("c:/本") do |dir|
irb(main):003:1* dir.each do |f|
irb(main):004:2* p f
irb(main):005:2> end
irb(main):006:1> end
"."
".."
=> #<Dir:0x3a1e55c>

Windows2000/VISTAの話で入れたのはActiveScriptRuby
"本稼動"だの"本番"だのが共有ディレクトリ内にあるんだな
0915デフォルトの名無しさん2007/01/17(水) 23:45:29
globはワイルドカードを展開するという意味の動詞。
0916デフォルトの名無しさん2007/01/18(木) 01:42:06
>>903
空のBindingを作ってから他のローカル変数を追加すればいい。

def empty_binding
  binding
end

def create_binding(h)
  b = empty_binding
  h = h.inject({}) {|hx, (var, val)| hx[var.to_s] = val; hx}
  arg = "__a"
  arg.succ! while h.key?(arg)
  eval((h.keys << "nil").join(" = "), b)
  h.each {|var, val| eval("proc {|__a|#{var}=__a}", b).call(val)}
  b
end

# テスト
b = create_binding(:a=>10, :b=>'foo', :c=>%w[x y z])
p eval("a", b)
p eval("b", b)
p eval("c", b)
p eval("h rescue $!", b)
p eval("__a rescue $!", b)

0917デフォルトの名無しさん2007/01/18(木) 19:10:20
完全マッチさせる方法を教えてください。

if /1/ =~ input
これだと、inputが11や111でもマッチしてしまいます。
input = 1の時だけマッチさせるにはどうすればよいでしょうか?
0918デフォルトの名無しさん2007/01/18(木) 19:16:31
/\A1\z/
0919デフォルトの名無しさん2007/01/18(木) 19:17:29
input == "1"
09209172007/01/18(木) 19:26:27
>>918
やってみたところ、1もマッチしなくなりました;

>>919
inputは入力されたものです。説明不足ですいません。
0921デフォルトの名無しさん2007/01/18(木) 19:34:54
/^1$/
0922デフォルトの名無しさん2007/01/18(木) 19:43:25
if input.chomp == "1"
09239172007/01/18(木) 19:43:32
>>921
>>918と同じく、1もマッチしなくなりました;
09249172007/01/18(木) 19:45:59
>>922
その方法でうまくいきました。
有り難うございました。
0925デフォルトの名無しさん2007/01/18(木) 21:19:40
いいのかそれで・・・
0926デフォルトの名無しさん2007/01/18(木) 21:48:40
単に改行を取り忘れたいただけ?
0927デフォルトの名無しさん2007/01/18(木) 22:05:48
だね。

/¥A1¥z/ =~ input.chomp
でもマッチするだろう。
0928デフォルトの名無しさん2007/01/18(木) 23:49:47
>>914
"本" のシフトJISコードの2バイト目が "{" なので
こいつをワイルドカード文字と誤認識して異常動作している
私も以前にこれに引っかかりました
Dir.open('ほげほげ').to_a
とかに変えた記憶があります
・ディレクトリエントリのみの配列になる
・ドットファイルも含まれる
・ディレクトリの再帰検索は出来ない
・パスデリミタとしてバックスラッシュも使える
という違いがありますが、大抵はこれで事足りるような気がします
シフトJISの呪いはいつまで続くのでしょうか
0929デフォルトの名無しさん2007/01/19(金) 00:04:28
>>928
-Ks で解決する問題とは違う?
0930デフォルトの名無しさん2007/01/19(金) 02:59:37
>>929
違う。純粋にglobingのルーチンの問題。

実は1.9で使われているglobingルーチンでは解決しているが、
なんのかんので1.8にバックポートされていない。
1.8.6で入れてくれ。ってリクエストしてもダメかねえ。

0931デフォルトの名無しさん2007/01/19(金) 12:02:48
最近テキスト処理なんかの事務作業のためRubyの勉強始めたんですが
リファレンスはHowToな対応できても基礎がわかってなくて不安です
で、高かったり厚くても問題ないので、1冊だけ読むならこれ、っていうお勧めの書籍ってなんでしょうか?

一応amazonとかみると「プログラミングRuby―達人プログラマーガイド」
が評判良さそうなのですが、>>281>>286でもあがってないし少し古いのでどうなんでしょか?
(ちなみに他言語はそこそこ触ってます
0932デフォルトの名無しさん2007/01/19(金) 12:21:54
他の言語使った経験あるなら
webの情報でなんとかなりますよ
0933デフォルトの名無しさん2007/01/19(金) 12:23:22
あ、あえて薦めるとしたら、
Rubyソースコード完全解説
RubyHackingGuide
09349312007/01/19(金) 12:46:59
サンクス

>webの情報でなんとか
割とそうですがそういうもんでしょうか

Rubyソースコード完全解説は趣旨と違うけど面白そう
0935デフォルトの名無しさん2007/01/19(金) 12:52:19
>>934
私はwebの情報を見ながらだけど
あなたと同じように
これで大丈夫なんかいな?
基礎分かって無いで使ってるけど?
みたいな心配がありました

ちょっと趣きを変えて
Rubyソースコード完全解説
を読んでみたら
読んだあとはすらすら使えるようになってました
0936デフォルトの名無しさん2007/01/19(金) 13:30:49
>>930
> 1.8.6で入れてくれ。ってリクエストしてもダメかねえ。

ちと、そのへんの強化策を考えないといかんかねぇ。
有用そうだけど1.9からバックポートされてないのというと、こんなところか。
* multibyte path globing
* large file support
* override by forwarding
0937デフォルトの名無しさん2007/01/19(金) 13:41:57
>>934
自分はJavaからやった。
Javaは書籍が豊富だから。

回り道のように思えるけど、自分はこっちの方が効率がいいと思っている。
0938デフォルトの名無しさん2007/01/19(金) 13:57:17
>>936
override by forwarding って何?
0939デフォルトの名無しさん2007/01/19(金) 17:51:41
学校の宿題で配列でHeapを実装しろとかでてきました(>_<)誰か教えてください。
0940デフォルトの名無しさん2007/01/19(金) 17:53:07
うむ、とりあえず、配列でヒープを実装するんだ。
0941デフォルトの名無しさん2007/01/19(金) 17:56:02
$stderr.print "\a" while 1

コレでいいだろ?
0942デフォルトの名無しさん2007/01/19(金) 18:27:11
>>939
東大生乙
09439392007/01/19(金) 19:37:21
いじわるしないで誰か教えてください(>_<)時間ないんです。ちなみに東大生じゃありません。
あとできればヒープソートの作り方も教えてください。
0944デフォルトの名無しさん2007/01/19(金) 19:43:16
二分ヒープなら、nの位置の親の子は
1始まり→2nと2n+1
0始まり→2n+1と2n+2
に入れればいい。
09459392007/01/19(金) 19:50:07
解答ありがとうございます。でもちょっとよくわかりませんね(;^_^A
自分でもうちょい考えたら改めて質問に来ます。
0946デフォルトの名無しさん2007/01/19(金) 20:28:02
そういうのは以降こっちで
http://pc10.2ch.net/test/read.cgi/tech/1106572657/
0947デフォルトの名無しさん2007/01/19(金) 20:28:36
宿題スレいけよ
09489392007/01/19(金) 23:10:16
>>946
おお!
こんなスレあったんですね!
0949デフォルトの名無しさん2007/01/20(土) 00:22:05
>>941
それはビープ。
0950デフォルトの名無しさん2007/01/20(土) 00:31:43
>>938
read()とかwrite()とかを#defineで置き換えてるのを、DLLのforwardingで置
き換えるようにするというのを勝手に「override by forwarding」と書いた。

ChangeLogにはaliasと書いてあったので、
「symbol alias by forwading」ということにしよう。

svnでいうとrevision 9502。
0951デフォルトの名無しさん2007/01/20(土) 00:39:08
つーか>>914は単にディレクトリが空だから
Dir.globが空Array返したってだけじゃないのか?
"*"はdot fileにはマッチしないんだから。
0952デフォルトの名無しさん2007/01/20(土) 04:19:11
>>936

coding pragma を追加したいところだけど、あれは1.8には持ってこれない
という話だから、それくらいかな?

ところで署名でも集めるの?w >強化策



0953デフォルトの名無しさん2007/01/20(土) 08:14:15
>>949
お前だけだ。分かってくれたのは・・・。
もう少して危ない人になるところだった。
0954デフォルトの名無しさん2007/01/20(土) 11:44:14
exerbについての質問です。
レシピファイル作成をスクリプトの実行と同時に自動で行う機能があるとのことですが、
ずっとループし続けるスクリプトの場合には、自動生成できないのでしょうか?


もしあれば教えてください。
0955デフォルトの名無しさん2007/01/20(土) 13:04:05
ループ一回したら終了するの作ってレシピ作ればいいじゃない
レス数が950を超えています。1000を超えると書き込みができなくなります。