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

Ruby について Part 3

レス数が950を超えています。1000を超えると書き込みができなくなります。
0001デフォルトの名無しさんNGNG
オブジェクト指向スクリプト言語Rubyについて扱うスレッドです。

Ruby Home Page
http://www.ruby-lang.org/ja/

<前スレ>
Rubyについて Part 2
http://pc3.2ch.net/test/read.cgi/tech/1028906179/

<過去スレ>
Rubyについて
http://pc3.2ch.net/test/read.cgi/tech/1012096319/
0855デフォルトの名無しさんNGNG
>>853
だから、そんな面倒なことしてちゃ、今の時代生き残れないよってこと言いた
かったんよ。
rubyでcalc作ってる。自分用のoptionもたくさんあって、これ最強。
0856デフォルトの名無しさんNGNG
訳の分からないことを言いたがらないでください。
0857デフォルトの名無しさんNGNG
>>855
おまえは生き残れない
0858デフォルトの名無しさんNGNG
なるほど!伊良部の略だったのか、なるほど。
で、伊良部とrubyのつながりはどこにあるのだろうか?

わからない
0859デフォルトの名無しさんNGNG
>>853
ではCに合わせてるとみてよろしいか
0860855NGNG
>>857
俺は生きる、生き抜いてやる。
0861デフォルトの名無しさんNGNG
計算機が欲しければ普通にmaximaとかmupad使うのがいいと思うけど。
お金があるならmathematicaとかmatlabを使えばいいわけで。
分数計算で十分なら irb -m でもいいだろうが変数の入った式は扱えない。
0862デフォルトの名無しさんNGNG
Emacsじゃ(/ 3 2) => 1 かもしれないけど
Xyzzyなら (/3 2) => 3/2 だよ。
有理数のまま計算していって、答えを出す手前で + 0.0 して実数に直すと
丸め誤差が少なくてイイ!
0863862NGNG
/ と 3 がくっついてしまった。
誤: Xyzzyなら (/3 2) => 3/2 だよ。
正: Xyzzyなら (/ 3 2) => 3/2 だよ。
0864デフォルトの名無しさんNGNG
>>854
なるほど。たしかにbench {...} の前に i=nil を入れると速度差は誤差の範囲になりました。
しかしブロックローカルの変数って何で遅いんだろ?
0865デフォルトの名無しさんNGNG
Rubyの勉強にruby-dbiとPostgresを利用してるのですが、
select文で取得したレコードの、日本語の部分が化けてしまうのです。
原因・解決方法など教えてもらえませんか・・・?

0866865NGNG
化けた文字は

テスト
\245\306\245\271\245\310

こんなかんじです。
0867デフォルトの名無しさんNGNG
>>866
pの多バイト文字の出力はそんな感じになる。
print/putsあたりを使えば?
0868865NGNG
>>867
なるほど。print/putsは日本語表示されました。
pはprintの略なのかなぁと思ってました。
ありがとうございあす。
0869デフォルトの名無しさんNGNG
>>868
あるいは$KCODEを指定しとく。
0870デフォルトの名無しさんNGNG
>>864
メソッドスコープのローカル変数は配列になってるのに対して、
ブロックローカルはIDとVALUEのlinked listになってるから、
それをたどる分だけ遅くなる。
0871デフォルトの名無しさんNGNG
>>870
やっぱり Ruby Hacking Guide を読まなきゃならんか。
0872デフォルトの名無しさんNGNG
>>870
あんたすげーよ。勉強になった。
0873デフォルトの名無しさんNGNG
インスタンス変数へのaccessorは attr_accessor :v1, v2, ... を
使うことで簡単に定義できる。
では、クラスインスタンス変数へのaccessorはどうすればよい?
今は
class Foo
def self.v1=(v)
v1=v
end
def self.v1
@v1
end
end
とチマチマ定義している。
これをもっと簡単に定義したい。
0874デフォルトの名無しさんNGNG
>>873
class Foo
class << self
attr_accessor :v1,:v2,:v3
end
end
0875デフォルトの名無しさんNGNG
ようやくwww.cygwin/setup.exeにrubyが標準搭載されたので
次はRuby.netがVS.NETで使えるようにして欲しい。
0876デフォルトの名無しさんNGNG
>>874
ごっつさんくす。
かなーりたすかった。
今度おごるよ。
0877デフォルトの名無しさんNGNG
>>874

この書き方だとRubyスクリプトとしてはまったく問題ないけど、
RDocがうまく解釈してくれないね。惜しい。

(RDocのバージョン:RDoc Vbeta-2: 2002/07/22 21:07:31 (1.67))
0878874NGNG
>>877
class Foo
 class << self
  # v1 - Foo's instance variable
  attr_accessor :v1
 end
 # v1 - Foo's attribute
 attr_accessor :v1
end

みたくコメントを工夫するしかなさそうだね。
0879デフォルトの名無しさんNGNG
>>878

あれー、それでうまくいった?
試したけど、どちらもインスタンス変数へのアクセッサと
してしか認識されなかったよ。
RDocのバージョンが古いのかな?
0880デフォルトの名無しさんNGNG
win32api の SendInput() を使いたいんですが、誰か書いてませんか。
引数が Struct 使う場合にどうすればいいのかよくわからないんです。
0881デフォルトの名無しさんNGNG
>880
配列をpackした文字列を渡す。
0882デフォルトの名無しさんNGNG
ブロックローカル変数をローカル変数と同様の実装にできないのはなんでだろ
0883デフォルトの名無しさんNGNG
>>882
Rite では直すのかな?
0884デフォルトの名無しさんNGNG
eRubyをはじめて使ってみたんだけど
index.rhtml:1:missing end delimiter (ERuby::CompileError)

こういうエラーがでてしまう。
何が悪いのだろうと調べて、キーワという文字列を抜くと動く。
日本語を含んだ文を書き出すには、なにか必要なのでしょうか。
0885デフォルトの名無しさんNGNG
よくは分からんがこういうことかな

require "kconv"
s = "ーワ".toeuc
d = ""
s.each_byte{|c| d << (c&0x7F)}
$KCODE = "n"
p s # "\241\274\245\357"
p d # "!<%o"

$KCODE を変えてみれば動くかも
0886デフォルトの名無しさんNGNG
Proc.new {|a|}.arity => -1 になるのが俺の悪い頭では理解できません。
引数の数だから、1 になるんじゃないかと思うんだけど、
なんで -1 になるのか誰か教えてー。
0887デフォルトの名無しさんNGNG
arityが-Nってのは、N-1個以上の引数を取れるって意味ってとこまではOK?
で、ブロック引数は多重代入と同じセマンティクスを持つので、

a = 1, 2, 3 # => a == [1,2,3]

と任意の個数の引数を取れるということ。

だったんだが、1.8.0 preview3ではそれは1になる模様。
0888デフォルトの名無しさんNGNG
Paint Shop Pro 8のマクロ言語としてPythonが採用されたそうだ。
Rubyが採用された市販アプリって有るのか?
まぁ、PSPは米国製だからってのもあるんだろうが。

つか、Rubyを採用しようにも、簡単に組み込めるようなライブラリが
無いよな? Pythonにはそれが有るらしいが(伝聞)。
そのへんどうにゃのよ?
0889デフォルトの名無しさんNGNG
Rubyも組み込むのはそんなに難しくないよ。
最近の俺的には、ネイティブスレッドに対応してないのでRubyは選べないけど。
0890886NGNG
>>887 さん
わかりやすい説明どうもありがとう。

> で、ブロック引数は多重代入と同じセマンティクスを持つので、
はじめて知りますた。。。
なるほど納得です。

> だったんだが、1.8.0 preview3ではそれは1になる模様。
ふむ!こっちのほうが俺にはわかりやすいです。

ためになる情報ありがとうございました。




0891デフォルトの名無しさんNGNG
>>887
> だったんだが、1.8.0 preview3ではそれは1になる模様。

lambda{|x|}[] とか def f() yield end ; f{|x|} が出来なくなるということ?
0892デフォルトの名無しさんNGNG
>>891
> lambda{|x|}[] とか def f() yield end ; f{|x|} が出来なくなるということ?
できるけど、警告が出る。

$ ruby -ve 'lambda{|x|}[]'
ruby 1.8.0 (2003-06-21) [i686-linux]
-e:1: warning: multiple values for a block parameter (0 for 1)

任意個の引数を取るときには|*x|、一個だけなら|x,|と書けば、1.6以前でも問題ない。

ちょうど同じ話題が出てる
ttp://jarp.jin.gr.jp/diary/200306c.html#200306211
0893デフォルトの名無しさんNGNG
>>888
Becky!用のRuby pluginってのはある。
あとtalkではたびたびアプリケーションに組込むって話がでてるけど、
具体的な製品名は分からない。
0894デフォルトの名無しさんNGNG
Rubyを自作アプリに組み込むHowToマニュアル出して欲しいな。
できれば、Win版とUNIX版両方で。
0895デフォルトの名無しさんNGNG
C++用だけどこういうのがあることはある。
ttp://metaeditor.sourceforge.net/embed/
0896デフォルトの名無しさんNGNG
>>892
ああ、それなら知ってるけど、どうしていまさら後方互換性をなくす方向に
動き出したんだろ。2.0への布石?
0897デフォルトの名無しさんNGNG
>>896
> 動き出したんだろ。2.0への布石?
そんなとこだと思うけど。
arityに関しては、たしかに分かりにくいという声が以前からあったし。
0898デフォルトの名無しさんNGNG
>>894
一時期の出版ラッシュのついでに出しておいてくれれば良かったのに。
0899デフォルトの名無しさんNGNG
>自作アプリへの組み込み
Cマガあたりに記事がなかったっけ?
Web上でも読めた気がする。
0900デフォルトの名無しさんNGNG
>>899
本じゃないが、erubyなんかはいい例にならないかな。
0901デフォルトの名無しさんNGNG
1.8.0 preview3出ますた。
0902784NGNG
標準入力ってなんでopenできないの。

>ruby -ve "File.open '-'"
ruby 1.6.8 (2002-12-24) [i386-mingw32]
-e:1:in `open': No such file or directory - "-" (Errno::ENOENT)
from -e:1
0903デフォルトの名無しさんNGNG
- は標準入力ではないです。
0904デフォルトの名無しさんNGNG
標準入力は $stdin
0905デフォルトの名無しさんNGNG
あぁ。すんません。
具体的に質問します。

コマンドラインでファイル名が指定されたらそれを、
指定されなければ標準入力を開くって処理をしたいんです。

Perl だと
push(@ARGV, "-") if no @ARGV
foreach (my $file @ARGV) {
open(F, $file);
#ほげほげ
}

とかできて楽なんですけど、Rubyだとどう書くんですか。
ファイル単位で(ファイル名を意識して)処理したいんで、ARGFは却下です。
0906デフォルトの名無しさんNGNG
>>905
なんかいろいろ間違ってる・・・Perl久しぶりとはいえ・・・欝だ。
0907デフォルトの名無しさんNGNG
ARGV.each do |file|
f = (file == '-' ? STDIN : open(file))
begin
# ほげほげ
ensure
f.close unless f == STDIN
end
end
0908デフォルトの名無しさんNGNG
def reading(file, &block)
if file == '-'
yield STDIN
else
open(file, &block)
end
end

ARGV.each do |file|
reading(file) do |f|
# ほげほげ
end
end

0909デフォルトの名無しさんNGNG
>>905
>ファイル単位で(ファイル名を意識して)処理
ARGF.file や ARGF.filename 使えば。
0910デフォルトの名無しさんNGNG
なんで場合わけしなきゃいけないの。
tar だって cat だって UnixTool はみんな - が標準入力じゃないか。
なんで STDIN を特別扱いしなきゃいけないだ。
めんどくさいだけじゃないか。

#ほげほげ

そうか、いろんな - がありえるんだ
- が標準入力じゃなくてもいいんだ。
Perl がやりすぎなんだ・・・
ボクは Ruby が好きなんだ!
ボクはここいいたい!!
ボクはここにいてもいいんだ!!!

ところで amrita って便利ですね。
0911デフォルトの名無しさんNGNG
>>909
> ARGF.file や ARGF.filename 使えば。
うーん。そうなんですけど、なんかうまくいかなくて。

やりたいのはファイル名とファイルの全内容を
もとに処理をしたいのです。

def hogehego(filename, content)
# ほげほげ
end

↑こんな感じ。で・・・

while not ARGF.eof?
puts ARGF.filename
puts ARGF.file.readlines.size
end

こうすると最初のファイルしか処理されなくて、
じゃあ while not ARGV.empty? ってすると
標準入力から読み込んでしまってわけわからん。

ARGFの挙動が理解できないんですけど。
0912784NGNG
>>911
こうすれば全ファイル処理された。

while not ARGF.eof?
puts ARGF.filename
puts ARGF.file.readlines
ARGF.skip
end

でもファイルを指定しなかった場合の挙動がいや・・・

というか誰か↓を解説してくれ。まじでわかんねぇ。

>ruby -e "puts ARGF.filename" hoge.rb
-

>ruby -e "ARGF.eof?; puts ARGF.filename" hoge.rb
hoge.rb
0913デフォルトの名無しさんNGNG
>>911
$ ruby -e '%w(foo bar).each{|f| File.open(f,"w") << "1\n1\n"}'
$ ruby -ne 'BEGIN{p ARGF.filename}; p ARGF.filename' foo bar
"-"
"foo"
"foo"
"bar"
"bar"
$ awk 'BEGIN{print FILENAME}; {print FILENAME}' foo bar

foo
foo
bar
bar
$
0914デフォルトの名無しさんNGNG
>912
ARGVで指定されたファイルを触るのをぎりぎりまで先送りにしたいからでは?
ファイルを開かないことには eof? の真偽を知ることが出来ないから
eof? のあとでは指定された名前のファイルの存在も分かる。
しかしfilenameを知るために(詳しくいえばfilenameで返される名前のファイルの
存在を保証するためだけに)ファイルを開くのは許せないとか。
存在を保証するためなら File::readable?(ARGV.first) という手もあるが、
readable? では実際に読みにいったときにファイルがまだあることを保証できない。
もっともこれだけでは最初にSTDINをさしている理由は説明できないがね。
0915RNGNG
ルビー初めて2週間目の初心者です。
いま、自分で考えているオンラインゲームがありまして
それの実現に、Rubyを使ったサーバプログラムを考えているので
第1歩として、多人数向けのチャットサーバを作ろうと思い作り始めたのですが

多人数向けのエコーサーバは「Rubyライブラリ編」を参考に(ほとんどそのまま)で
つくり、うまくいったのですが、ある端末から他の端末へ文字を送る方法で
悩んでいます。

配列を使い、TCPServerのインスタンスを配列の中に入れようと考えたのですが
どうも、うまくいきません。
先輩方、どうかアドバイスをお願いいたします。
0916デフォルトの名無しさんNGNG
>>915
「どこまでやって、どこでつまづいたか」を具体的に書いた方が
回答を得やすいと思われ。
0917RNGNG
>916
はい、了解しました。
エコーサーバを改造してこんな風に書いてみたんです。
require "socket"
gs = TCPServer.open(8888)
online = []
while TRUE
ns = gs.accept
print(ns, " is accepted\n")
Thread.start {
s = ns
online.push(ns)
while str = s.gets
x = 1
while x <= online.size do
online[x].write(str)
x+=1
end
end
print(s, " is gone\n")
s.close
}
end
うまくいけば、接続している人全部にメッセージを送ることが
できるはずなんですが、誰にもメッセージが帰ってこないのです。
自分なりに調べたところでは、配列の中身がいつの間にか
無くなっているっぽいのです。
0918デフォルトの名無しさんNGNG
>>917
とりあえず、while str = s.gets ... end の中がよくわかんないんだけど、
こんなんでどう?

online.each do |c|
c.write(str)
end

あとは、s.close のあとで online.delete(s) とか。
0919RNGNG
>918
うまくいきました、ありがとうございます。
while str = s.gets ... end の中が間違っていたってことなんですよね
どこが良くなかったのだろ?
でも、online.each使ったほうが簡潔で解りやすいですね。

またお世話になるかもしれません。そのときは皆様よろしくお願いいたします。
0920デフォルトの名無しさんNGNG
>>919
クライアントが一つだけ接続に来たとき、そのソケットは online[0] のはずだが、
x = 1 から始まるので online[1] を参照にいき、online[1] == nil であるから、
nil.write(str) が実行される。この時点でそのスレッドは死ぬが、
デフォルトでは Thread 内で例外が起こっても黙っているので分かりにくい。
ruby -d server.rb のように -d つきで実行すると上の状況が分かるだろう。
0921デフォルトの名無しさんNGNG
>>917 もう見てないかも知れんが、
> Thread.start {
> s = ns
> online.push(ns)

もし online.push(ns) する前にメインスレッドに切り替わって
ns = gs.accept が成立すると、ns は予期しないものになっている。
よってこうした方が良い

Thread.start(ns) { |s|
online.push(s)

あるいはロジックは少し変わるがこれでも良い

online.push(ns)
Thread.start(ns) { |s|
0922RNGNG
>920
配列は、0からはじまるのですか。
だからnilを参照してたのですね。
自分の間違えが、わかりすっきりしました。

>921
了解しました。
仰るとおりに、タイミングしだいではnsは
不定になります。
下のほうが、より確実っぽい気がするので
これでいってみたいと思います。

みなさま、ありがとうございました
0923デフォルトの名無しさんNGNG
def f0
aa = 111 #0
return binding
end
def f1(bb, a_bind) #1
cc = 222 #2
eval "p aa, bb, cc", a_bind #3
end
f1(333, f0)

上のスクリプトで、#3 の eval のとき、aa(#0), bb(#1), cc(#2)
の指すオブジェクトを eval に評価させる式の中でいっしょに使い
たいのですが、よい方法はあるでしょうか? この場合の結果は
111
333
222
が欲しいということになります。

質問の意図がわかりにくいかと思いますが、誰か教えてくれるとうれしい。
0924デフォルトの名無しさんNGNG
これじゃあかん?

def f0
aa = 111 #0
return binding
end
def f1(bb, a_bind) #1
aa = eval("aa", a_bind)
cc = 222 #2
eval "p aa, bb, cc" #, a_bind #3
end
f1(333, f0)
0925923NGNG
>>924
解答ありがとう。でもそれではだめなんです。923で説明が足りなくてスマソ。

f1の定義の時点で a_bind のコンテキストに存在する変数aaについては知らんのです。

#3 のところでやりたいことは、a_bindにメソッドf1の定義で出てきたローカル変数を
追加したコンテキストで #3 の行の評価をする、ということです。以下のスクリプト
の方が923のより多少は意図が伝わりやすいかも…


def f0
aa = 111 #0
return binding
end
def f1(bb, expr, a_bind) #1
cc = 222 #2
eval expr, a_bind #3
end
f1(333, "p aa, bb, cc", f0) #4
0926923NGNG
923のスクリプトは、私のやりたいことの意図を正確にあらわして
いませんでした、すまそ。以下のスクリプトみたいな方法で、とり
あえず問題は解決できそうです。

class Data
attr_accessor :aa
end

def hoge(bb, expr, bind)
data = eval("self", bind)
cc = 111
data.instance_eval(expr)
end

d = Data.new
d.aa = 222
bind = d.instance_eval { binding }

hoge(333, "p aa, bb, cc", bind)
0927デフォルトの名無しさんNGNG
なにー!せっかく考えたから送る

def empty_binding
  binding
end

def marged_binding(*bindings)
  dst = empty_binding
  bindings.each do |src|
    eval("local_variables",src).each do |var|
      id = eval(var, src).id
      eval("#{var} = ObjectSpace._id2ref(#{id})", dst)
    end
  end
  dst
end

def f0
  aa = 111                     #0
  return binding
end

def f1(bb, expr, a_bind)       #1
  cc = 222                     #2
  eval expr, marged_binding(binding, a_bind)
end
f1(333, "p aa, bb, cc", f0)    #4
0928923NGNG
>>927
なんかすげー。理解するのにちょっと時間がかかりそうだけど、使えそうな予感。
ありがとう!
0929デフォルトの名無しさんNGNG
>>926
Dataは標準の組込みクラスで、new(1.6)やallocate(1.8)は定義されてない。
0930デフォルトの名無しさんNGNG
Data って Ruby API だけ使ってる人は知らない罠
0931デフォルトの名無しさんNGNG
>>930
まぁそうだろうな。
ともあれDataのインスタンスは作れないし、拡張ライブラリ使うならDataはい
じらんほうが身のため。
0932デフォルトの名無しさんNGNG
そりゃそうなんだけどDataってそれほど存在が知られてない割に
名前が一般的過ぎてよくないよね。
0933デフォルトの名無しさんNGNG
なんか、知らずに Data ってクラス作って(使って)ハマりそう・・・

つか、漏れは obj.id とか obj.hash とかでハマったことあり・・・
0934デフォルトの名無しさんNGNG
>>933
idははまったなあ。hashは知ってたんで、はまったことないけど。
0935デフォルトの名無しさんNGNG
Kernel#idは廃止予定。
__id__かobject_idならかぶらんだろ。
0936デフォルトの名無しさんNGNG
Data -> ExternalData とかに変更してほしい
0937デフォルトの名無しさんNGNG
まずは、二つのプログラム
1.
while $in = STDIN.gets
$in.chomp!
print $in + "\n"
end

2.
while $in = "11"
print $in + "\n"
end

なぜ1のプログラムは動いて、2のプログラムは
動かないのでしょうか?
僕が考えると、1が動く方が不思議なんですが。
というのも、while文というのがwhileのうしろが
trueの時に処理を行なっているのなら、
上のプログラムのように、whileの後で代入をおこなっている(つまり、なにも値を返していない)
ような場合は、ともにエラーがでると思います。

どう考えればいいのでしょうか?
0938デフォルトの名無しさんNGNG
ありゃ、Dataってクラスは作れないのか。初めて知った。
とは言え、Dataという名前のクラスは作りそうで作らない気がする。
0939デフォルトの名無しさんNGNG
さて、まず>>937が釣か否かが問題となるわけだが
0940デフォルトの名無しさんNGNG
「>>937は釣りである」の値はtrueとなるので問題ないと思います。
0941937NGNG
釣りでないです。
プログラミング自体、畑違いなので
聞ける人がまわりにいません。
教えてください。お願いします。
0942デフォルトの名無しさんNGNG
>>937
2のほうも動くだろ。
0943デフォルトの名無しさんNGNG
↓↓↓釣りにマジレス
0944デフォルトの名無しさんNGNG
>>937
次の二点を確認して、放課後までに職員室に来なさい。

・代入は値を返さない?
・偽はfalseとnil。では真は?
0945デフォルトの名無しさんNGNG
C言語の関数で、rintとlogに成り代わる関数ってなんでしょう?
0946デフォルトの名無しさんNGNG
>>945
C言語の質問?
0947デフォルトの名無しさんNGNG
>>946
rubyの質問なんですが・・・?
0948デフォルトの名無しさんNGNG
まず日本語の勉強を・・・
0949デフォルトの名無しさんNGNG
ライブラリ同士の名前空間の重複を回避したいのです、例えば、

hoge1.rb:
class Hoge
def hoge
"ほげ1"
end
end

hoge2.rb:
class Hoge
def hoge
"ほげ2"
end
end

があるとき、自前でファイルを開いて

require 'hoge1'

module A; end

File.open("./hoge2.rb"){|f|
A.module_eval f.read
}

p Hoge.new.hoge   #=>"ほげ1"
p A::Hoge.new.hoge #=>"ほげ2"

のようにやっているのです、もっとシンプルにTop Levelではなくユーザの導入した名前空間への
requireやloadのようなことを行う方法はありますか?
0950945NGNG
>>948
私の発言のなにが解らないのか教えてもらえますか?
0951デフォルトの名無しさんNGNG
「C言語の関数で、」なら答えはC言語の関数でなければならないのだが…

もしも「C の rint と log に相当するのはRubyでは何?」ってことなら、
log(x) は Math::log(x) で rint(x) は x.round

ちなみに rint は C の標準関数じゃないよ。
0952デフォルトの名無しさんNGNG
>>950
句読点の使い方
0953デフォルトの名無しさんNGNG
>>949
今んとこ、ない。loadの第二引数にModuleを使えるように、という話はtalkで
ちょっとだけ出てるようだ。
0954デフォルトの名無しさんNGNG
>>938
作れないわけじゃないよ。

消しちゃうなり、Object以外を継承させれば別物になる。
class Object;remove_const(:Data);end
class Data < NilClass;end
レス数が950を超えています。1000を超えると書き込みができなくなります。