[#33716] Re: set_path_for_r — "HAYAMA_Kaoru" <iyamatta.hayama@...>
はじめまして、葉山と申します。
[#33732] 文字列の式展開について — Masao Mutoh <mutoh@...>
むとうです。
むとうです。
たけ(tk)です。
むとうです。
たけ(tk)です。
たけ(tk)です。
[#33736] Redefinition of builtin class — Shin-ichiro HARA <sinara@...>
原です。
まつもと ゆきひろです
[#33740] Net::SMTP.start の引数 — URA Takefumi <hage@...>
浦です。
[#33762] WebDAV client — HIDAKA Takahiro <cv8t-hdk@...>
ひだかです。
こんにちは、サイトウという者です。
[#33785] NET:HTTP get2 のエラー回避 — Takashi Hoshizawa <t_hoshizawa@...>
星澤といいます。
[#33793] 右辺の値なしでも実行可能? — "井上 浩一" <kyoui32@...>
井上です。
早瀬@大阪大学基礎工学部情報科学科 です。
まつもと ゆきひろです
早瀬@阪大です。
In article <20020211224442.48d0e668.hayase@hcn.zaq.ne.jp>,
なかだです。
> > > あえて宣言文の途中で、代入前に変数の値を使った場合にエラーを出そうと思うと、
なかだです。
高橋征義です。
るびべん です:
At Tue, 12 Feb 2002 13:27:58 +0900,
Takaaki Tateishi <ttate@kt.jaist.ac.jp> wrote:
[#33795] Re: 右辺の値なしでも実行可能? — "井上 浩一" <kyoui32@...>
井上です。
At Fri, 8 Feb 2002 12:21:53 +0900,
[#33802] Re: 右辺の値なしでも実行可能? — "井上 浩一" <kyoui32@...>
井上です。
[#33807] Re: 右辺の値なしでも実行可能? — "井上 浩一" <kyoui32@...>
井上です。
jihg です。新入りです。
In article <000001c1b0c1$04eca980$b7d08bcb@soteccomputer>,
坂野 正明と申します。
At Tue, 12 Feb 2002 19:14:03 +0900,
坂野 正明です。
At Wed, 13 Feb 2002 02:14:39 +0900,
> Pseudo-Simplicity(擬似単純性)
Hiromasa KONISHIです。
jihg です。里谷がメダル取れたのはうれしい。開幕前の扱い悪かったから。明
[#33846] quickml サーバ — Satoru Takabayashi <satoru@...>
高林と申します
るびべん です:
まつもと ゆきひろです
るびべん です:
るびべん です:
こんにちは。鈴木教郎です。
[#33848] xxとして出し入れするメソッドの名前は? — Take_tk <ggb03124@...>
Apollo の話で恐縮なのですが、
[#33889] Ruby スクリプトサーバ + アプリと Apache+CGI アプリ — "井上 浩一" <kyoui32@...>
井上です。
[#33893] Re: Ruby スクリプトサーバ + アプリと Apache+CGI アプリ — "井上 浩一" <kyoui32@...>
井上です。
[#33906] Re: Ruby スクリプトサーバ + アプリと Apache+CGI アプリ — "井上 浩一" <kyoui32@...>
井上です。
[#33915] Re: Ruby スクリプトサーバ + アプリと Apache+CGI アプリ — "井上 浩一" <kyoui32@...>
井上です。
[#33926] 破壊的な代入について — Himuro UTO <himuro-uto@...>
ひむろ と申します。
[#33959] Re: Ruby スクリプトサーバ + アプリと Apache+CGI アプリ — "井上 浩一" <kyoui32@...>
井上です。
[#33962] Re: Ruby スクリプトサーバ + アプリと Apache+CGI アプリ — "井上 浩一" <kyoui32@...>
井上です。
[#33964] pdflib-0.7 PDF クラスの継承について — "Makoto Matsukawa" <racer-m@...>
初めて投稿します松川と申します。Rubyは初心者で
[#33966] 「たまてばこ」開発版が SecurityE rror — dellin <dellin@...>
dellinといいます。
なかだです。
西山和広です。
なかだです。
まつもと ゆきひろです
なかだです。
[#33988] FileTest.exist?("") の値の UNIX と Windows との違い — Akira Suzuki <a-suzuki@...>
鈴木です。
なかだです。
In article <200202210337.g1L3b0726778@sharui.nakada.kanuma.tochigi.jp>,
[#33994] Shell#expand_path に ~ の入ったパスを渡したとき — Hiroshi Saito <HiroshiSaito@...>
サイトウという者です。
[#33997] JOLT award — matz@... (Yukihiro Matsumoto)
まつもと ゆきひろです
[#34006] for_fd したソケットの close — HIRATA Naoto <hirata-naoto@...>
平田といいます.
まつもと ゆきひろです
[#34010] si-bu-ra-gu — MAP2303@...
[#34015] 現在使用中の ruby.dll のパスは分かりますか?。 — Take_tk <ggb03124@...>
起動されたスクリプトの中から、そのスクリプトで使用中の ruby.dll のパスを
[#34021] localized document — HIDAKA Takahiro <cv8t-hdk@...>
ひだか%おもいきり現実逃避中です。
須賀です。
ひだかです。まとめて返事を書いてしまいます。
高橋征義です。
[#34030] Ruby Gem Box — Noritsugu Nakamura <nnakamur@...>
[#34053] 漢数字 -> 数 — TOYOFUKU Chikanobu <toyofuku@...>
豊福です。
# 本題と関係ありません。
池田と申します。
[#34056] ruby-dev summary — TAKAHASHI Masayoshi <maki@...>
高橋征義です。
たけ(tk)です。
まつもと ゆきひろです
[#34087] already initialized constant — 島田喜郎 <shimada@...>
島田喜郎と申します。教えてください。
[#34107] File#pos とファイルへの書き込み位置との整合性 — 堀川 久 <vzw00011@...>
こんにちは。
In article <3c7c7245.7413%vzw00011@nifty.ne.jp>,
[#34127] singleton class and anonymous class — matz@... (Yukihiro Matsumoto)
まつもと ゆきひろです
[ruby-list:33944] [Summary]arguments for def (Ver.2)
坂野 正明です。
以下、def の引数に関しての Summary 改定版(Ver.2) を投稿します。
# jihg さん、修正点の投稿をどうもありがとうございました。
# 取り込ませて頂きました。
#-------------------- Summary (revised=Ver.2) --------------------------
[Q]
Ruby の def 文においては、引数の受渡しは、多重代入と大体同じ
(違いは引数の数のミスマッチに関する厳しさだけ?)。よって、
def文の中で、破壊的メソッドを使う時は要注意。引数にとった
オブジェクトを誤って"破壊"しないためには、どうすればいいか?
# なお、Numeric, True/False/NilClass, Procクラスなどには破壊的
# メソッドは存在しない(immutable: 不変)ので、気にしなくてもいい。
[A1] (正当派?)
defの内部で(引数で渡されたオブジェクトに対して)破壊的なメソッドを
適用しない。
# オブジェクト指向の場合、現在の変数が指している実体のオブジェクトが何か
# を、常に意識しながらプログラミングすることが本質的に求められている?
[A2] (名付け派?)
(上と同じだが、誤らない工夫として)
defの際に、引数の名前に"in_"とか"out_"とかを付ける。
[A3] (慎重派?)
予想外のことが起こっていないか、しっかり、テストする。
rubyunit などが有用。
cf. http://homepage1.nifty.com/markey/ruby/rubyunit/
[A4] (lint派?)
予想外のことが起こっていないか、外部プログラムでテストする。
jihg さんのプログラムを、末尾 [付録1] に添付している。
[A5] (自爆派?)
def で受け取った引数に対し、ただちに .freeze する。誤って破壊的
メソッドを適用すると、エラーが出るので、チェックできる。
(長所)
・チェックが容易。
おそらく、エラーメッセージから直ちに問題箇所を発見できる。
(難点)
・複雑な分岐があると、チェック洩れの可能性あり(これは上[A3]と同じ)。
・一旦、.freeze すると、その解除はできない。
・freeze 自体が、オブジェクトの状態を(グローバルに)変更する。
つまり、def を呼んだルーチンの方でも当然この変更が有効になる。
かつ、解除できないから、しばしば困ることになるだろう。
・どちらにせよ、グローバルな状態を変更する def 文は、汎用的には
なりにくいので、debug が終わって本番の時には、外すべきか。
[A6] (邪道派?)
def で 引数を受け取った直後に、他の変数(もしくは自分自身)に .clone する。
(注意点1)
immutable なオブジェクトは .clone が未定義(のことが多い)
なので、要注意。
(注意点2)
.clone は、オブジェクト自身をコピーするのであって、オブジェクト
が指し示す他のオブジェクトまで再帰的にコピーするわけではない。
例えば、a=[x];b=a.clone; とした場合、a[0].equal?(b[0]) は true。
つまり、特に Array や Hash オブジェクトに対しては、たとえ .clone
しても、破壊的メソッドの適用は慎重に行うべし。
これを簡単に行うためには、例えば、以下のような方法があるだろう。
# 以下の方法では、上の注意点1は意識しなくてもよいが、注意点2は
# 依然意識しなくてはならない。
○方法I
I-1. 以下のファイル( make_clones.rb )を用意して、ライブラリパスに置く。
#--- ここから
def make_clones( bind, names )
names.gsub(/[*&]/,'').split( "[, ]+" ).each do | name |
eval( "#{name} = #{name}.clone rescue nil", bind )
end
end
#--- ここまで
I-2. ruby -rmake_clones で make_clones.rb を require。
I-3. def 文において、
def xyz(a,b,*c)
make_clones( binding, "a,b,c" )
...
などとして、最初に一気に引数を(同じ名前で) .clone する
# "*obj" などの場合は、"*"を外すこと。
○方法II
II-1. 以下のファイル( clone.rb )を用意して、ライブラリパスに置く。
#--- ここから
def clone(*a)
if a.size == 1
a[0].clone rescue a[0]
else
a.map{|i| i.clone rescue i}
end
end
#--- ここまで
II-2. ruby -rclone で clone.rb を require。
II-3. def 文において、
def xyz(a,b,*c)
a,b,*c=clone(a,b,*c)
...
などとして、最初に一気に引数を(同じ名前で) .clone する
# Editor で引数部を丸ごとコピーすればいい (default値の設定がなければ)。
[感謝!]
鈴木 さま
まつもと ゆきひろ さま
斉藤 秀格 さま
中田 伸悦 さま
新井康司 (Koji Arai) さま
原 (信) さま
jihg さま
[参考] (@ruby-list)
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/21159
「メソッドの入り口」に始まるスレッド
http://blade.nagaokaut.ac.jp/ruby/ruby-list/thr21063-21820.html#root_21159
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/21267
「引数コピーとオブジェクト指向(Re: メソッドの入り口)」に始まるスレッド
http://blade.nagaokaut.ac.jp/ruby/ruby-list/thr21063-21820.html#root_21267
[付録1]
「def の引数に対して破壊的メソッドを使っていたら警告する lint風プログラム」
(jihg さん作成)
オリジナルは (テストサンプルも含まれる)
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/33921
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/33925
(坂野による)修正点は
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/33927
jihg さんによる修正点が (およびテストサンプルの追加も)
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/33938
にあります。
+----------------- 説明
=begin
=機能
引数を破壊する操作を警告する。感度が高い。
=対象
組み込みクラス String ,Array ,Hash の破壊的メソッド。
自作クラスの破壊的メソッドには対応していない。
※課題。
=制約
関数定義は、def と end のインデントがバイト単位で同一でなければならな
い。
def foo(arg)
end # 無視される
arg << "break!" # 警告
次のような形式は許されない。
def foo(arg); ... ;end
def 〜 end を入れ子にすることは出来ない。
def foo(arg)
arg << "break!" # 警告
eval <<EOS
def bar # ここから変わってしまう
end # ここで終わり
EOS
arg << "break!" # 警告されない
ebd
def 〜 end 内に、バイト単位で同一のインデントを持つ end を置くことは出来
ない。
def foo(arg)
if flag
true
end # ここを def の終わりと認識する。
arg << "break!" # 警告されない
end
def 〜 end の構文および対関係が適正でなければならない。
def foo(arg # 閉じ括弧がない
end
Def foo(arg) # Def は間違い
end
def foo(arg) # end が存在しない
以下は検出できない。
def bar(a ,b)
eval(a)
end
def foo(arg)
bar("b << \"break!\"" ,arg)
end
def abc (a)
b=a
b.xxx!
end
=参考文献
「Ruby プログラミング入門」
原信一郎 著,まつもとゆきひろ 監修,オーム社
=end
+----------------- 本体
flnm = ARGV.shift
open(flnm ,"r") do |flh|
row = 1
count = 0
re = nil
reEnd = nil
while line = flh.gets
line.scan(/(?:^|\s+|;)def\s+.+?\((.*?)\)/i) do |s|
sRE = (s[0].split(/\s*,\s*/)).each do |ss|
next if /^\s*\&/ =~ ss
ss.sub!(/^\s*\*/,'')
ss.gsub!(/(.+?)\s*(?:$|=.*)/){ $1 }
end.join("|")
re = /[^\w@$\.](#{sRE})
(?:
(?:
\.
(?:
(?:
(?:replace)
|(?:push|unshift|pop|shift|concat|clear|fill)
|(?:store|delete(?:_if|_at)?|update)
)
\b|\w+!
)
)
|(?:\s*(?:<<))
|(?:\[.+?\]\s*=\s*)
)
/x
sREEnd = line.scan(/\s*/)[0]
reEnd = /^#{sREEnd}end\b/
end
unless re.nil?
line.scan(re) do |sArg|
print "warning : #{flnm}(#{row})---" +
" 引数 #{sArg} に対し破壊的な操作をしています。" +
"'#{line.scan(/(.*?)(?:\r\n|\r|\n)/)}'\n"
count += 1
end
re = nil if reEnd =~ line
end
row += 1
end
puts "(#{count})count."
end
#Version 2002.2.13 -> 14?
+----------------- ここまで
[付録2]
「immutable なオブジェクトについて」
immutable なオブジェクトかどうかは、以下のように判定できる
(immutable なオブジェクトは clone できないことを利用)。
class Object
def immutable?
begin
self.clone
false
rescue TypeError
true # clone できなければ、immutable
end
end
end
ただし、1.6 では Numeric 系で上記が通用しないので、
class Object
def immutable?
begin
self.equal?(self.clone)
rescue TypeError
true # clone できなければ、immutable
end
end
end
の方が良い。
#-------------------- Summary ここまで --------------------------