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

Ruby 初心者スレッド Part 30

レス数が1000を超えています。これ以上書き込みはできません。
0001デフォルトの名無しさん2009/08/08(土) 08:21:23
プログラミング言語Rubyについての、初心者向けスレです。質問・要望・雑談などどうぞ。

★注意★ Ruby 1.9.1 は初心者には時期早尚です。初心者には Ruby 1.8.7 を強くお勧めします。
   (理由:現時点では多くの有名ライブラリやアプリが 1.9.1 に未対応であるためです。)
 なお 1.8.7 でも 1.9 系に導入された新機能のいくつかが利用可能なため、1.8.7 で勉強すれば将来スムーズに 1.9 系に移行できるでしょう。

関連スレや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を読め」でいいので、叩かない&怖がらせない。
 ・わけわかな質問にもエスパー発揮で。できれば質問の仕方を教えるぐらいで。
 ・自信がない回答ならその旨表明すること。誤った回答は初心者じゃ見抜けない。
0951デフォルトの名無しさん2009/09/15(火) 12:09:44
require自体がファイル単位を扱うメソッドなんだからファイル名依存になるのは当たり前だろ
09529492009/09/15(火) 12:17:34
>>950
ありがとうございます!どちらも気づきませんでした・・・
プログラムを書き換えてみての動作確認もうまくいきました。
0953デフォルトの名無しさん2009/09/15(火) 12:38:57
>>951
requireされてるかわからないということは自分以外がrequireしたってことだから
ファイル名を知らないし知る必要もないと思う

require 'lib/example'
require './lib/example'
$LOAD_PATH << "lib/"
require 'example'
とりあえず実際問題として、$"ではこれらが区別されるから(requireも二重ロードをする)
>>950のようなduck type的アプローチのほうがよいかと
0954デフォルトの名無しさん2009/09/15(火) 13:12:18
Rubyでよく言うダックタイピングってJavaなんかで言うポリモーフィズムのことですか?
実装の違いは別として機能的には。
0955デフォルトの名無しさん2009/09/15(火) 13:22:04
アドホック
0956デフォルトの名無しさん2009/09/15(火) 13:44:37
>>954
だいたい合ってる

あえて区別するなら、ポリモーフィズムはクラスC1とC2に何かしらの関係性が産まれる
(スーパークラスが同じとか、インターフェイス/モジュールに同じモノを使うとか)
ダックタイプはメソッドに応答するだけでいい

「共通であるから同じに扱う」と「同じに扱えたから共通だと見なす」という感じ
0957デフォルトの名無しさん2009/09/15(火) 13:48:21
・・・とは言ったものの、ポリモーフィズム自体にそういう定義はないと思う
たぶん、関係性が産まれている場面でばかり使われていたから
関係性がないことを強調した言葉として派生させたのがダックタイプなんじゃないかな
0958デフォルトの名無しさん2009/09/15(火) 15:42:31
>>953
あと、require だと拡張子が省けるが、$" の中には拡張子込みで
入るので、実装を気にする必要も出てくる。
0959デフォルトの名無しさん2009/09/15(火) 16:58:31
拡張子込みとは言っても ".rb" か ".so" のどちらかじゃない?
0960デフォルトの名無しさん2009/09/15(火) 17:49:11
Macだと nkf.bundle になってたりする。
0961デフォルトの名無しさん2009/09/15(火) 17:56:21
>>948
self.class::B.new
0962デフォルトの名無しさん2009/09/15(火) 19:54:22
>>961
それだと A::B と解釈されるからダメ
0963デフォルトの名無しさん2009/09/15(火) 20:01:34
>>960
えーそれってMRI(YARV)? それともRubyCocoaとか?
0964デフォルトの名無しさん2009/09/15(火) 20:11:43
そもそも>>946の設定からしてわかりにくいんだよな、定数かぶりまくってるし
module M
 module A; end
 module B; end
end
class C
 class A; include M::A; end
 class B; end
end
こういうことなんだろうか

つーかこの状況だとModule.nesting使えないのか・・・
泥臭い方法以外でC::AのインスタンスからCを得る方法ってあるの?
0965デフォルトの名無しさん2009/09/15(火) 20:47:47
>>963
$ uname -a
Darwin aries.local 9.8.0 Darwin Kernel Version 9.8.0: Wed Jul 15 16:55:01 PDT 2009; root:xnu-1228.15.4~1/RELEASE_I386 i386 i386 iMac9,1 Darwin
$/usr/bin/ruby -v -rnkf -e 'p $"'
ruby 1.8.6 (2008-08-11 patchlevel 287) [universal-darwin9.0]
["nkf.bundle"]
0966デフォルトの名無しさん2009/09/15(火) 20:52:36
こっちも一応。

$ /usr/local/bin/ruby -v -e 'p $"'
ruby 1.9.2dev (2009-09-08 trunk 24795) [i386-darwin9.8.0]
["enumerator.so",
"/usr/local/lib/ruby/1.9.1/i386-darwin9.8.0/enc/encdb.bundle",
"/usr/local/lib/ruby/1.9.1/i386-darwin9.8.0/enc/trans/transdb.bundle",
"/usr/local/lib/ruby/1.9.1/rubygems.rb" ]

-rnkfすると enc/euc_jp.bundle とか混ざって長くなるので省いた。
0967デフォルトの名無しさん2009/09/15(火) 22:12:09
>>963
基本的にシステム固有のsuffixが使われる。
例外は、ライブラリにlibなどのprefixをつける慣習がないWindows等DOSISH系。
たとえば、libiconvのiconv.dllと拡張ライブラリのiconv.dllが区別つかなく
なるという事態を避けるため、後者を.soにしている。
0968デフォルトの名無しさん2009/09/15(火) 22:48:23
>>966
なんで enumerator.bundle じゃないんだろう。
0969デフォルトの名無しさん2009/09/16(水) 02:31:22
requireをロックするため突っ込んである
実際に探索したわけでもないパスだから。
0970デフォルトの名無しさん2009/09/16(水) 04:32:19
ume
0971デフォルトの名無しさん2009/09/16(水) 04:47:18
どうしてルビーなの?
なんでpythonじゃなくてルビーなの?
開発者が日本人だから?愛国心ってやつ?ねえ?
0972デフォルトの名無しさん2009/09/16(水) 05:42:56
あなたがPerlでもPHPでもSchemeでもなくPythonを使っているのと同じようなレベルの理由です
0973デフォルトの名無しさん2009/09/16(水) 06:59:09
>>971
煽りに使えそうな反論が出たらpythonスレに張り付けに行くんだろ?
0974デフォルトの名無しさん2009/09/16(水) 08:11:47
yes i do
0975デフォルトの名無しさん2009/09/16(水) 09:57:02
class C
def initialize
hoge
hoge = Array.new
hoge
end

def hoge
puts "参照メソッド呼ばれましたん"
end

def hoge=(arg)
puts "代入メソッド呼ばれましたん"
@hoge=arg
end
end

C.new

これはやっぱり

参照メソッド呼ばれましたん
代入メソッド呼ばれましたん
参照メソッド呼ばれましたん

であるべきなんじゃないかと思う今日この頃
っていうかこのへんの動作に依存したスクリプト作るのやめれ紛らわしいわぼけーうおー
0976デフォルトの名無しさん2009/09/16(水) 10:01:11
Pythonスレから刺客が来たと聞いて
0977デフォルトの名無しさん2009/09/16(水) 10:30:57
ローカル変数代入だけはちょっと特別なんだよね
代入の形したメソッドがある場合はどっち使うのか注意
0978デフォルトの名無しさん2009/09/16(水) 10:35:22
識別名がまずローカル変数、でなければインスタンスメソッドと
決定されるのは自然な発想では

ただ確かに紛らわしいから、結局
>このへんの動作に依存したスクリプト作るのやめれ
じゃなかろうか
0979デフォルトの名無しさん2009/09/16(水) 10:41:58
間違ってる人がいそうだから注釈するが、>>975は代入メソッド1回も呼ばれてないぞ
hoge= というインスタンスメソッドがあっても、hoge=Array.new はローカル変数への代入だ
= つきのインスタンスメソッドを呼びたい場合はレシーバが必須になる
この場合は self をつけて self.hoge=Array.new だな

これに def hoge; @hogeを処理して返す; end が加わってると混迷を増す
0980デフォルトの名無しさん2009/09/16(水) 12:00:21
ローカル変数の方がメソッドよりスコープ狭いんだから、ローカル変数が最優先で名前解決されるのは当然のように思える。
0981デフォルトの名無しさん2009/09/16(水) 13:23:01
>>978
呼び出しはそれでいいんだけど、>>977も言うようにキモは代入でしょ
ローカル変数とインスタンスメソッドに同じ名前さえ付けなければ
この手の問題は起きないと思ってる人はわりといるはず、つーか俺

>>980
存在するローカル変数と存在するインスタンスメソッドなら同意
まだ存在しないローカル変数と存在するインスタンスメソッドだったら、存在する方が優先に思える

「代入もメソッド呼び出しである」と考えると
変数hogeがないときにself.hogeが呼ばれる動作と対称的ではないのが違和感の原因
「疑わしきはローカル変数と見なす」も理解はできるけどね
0982デフォルトの名無しさん2009/09/16(水) 13:57:45
まあ世の中にはいろんなバックボーンを持った人がいるから、Rubyのルールが気持ち悪い/気にくわない/落ち着かないという人も大勢いるだろう。
それは仕方ない。そういうもんです、慣れてくださいとお願いするしかない。

ただまあ、代入に関して言えば、
・foo = 123 は変数への代入
・obj.foo = 123 は setter メソッドの呼び出し
というルールが分かっていれば、そう混乱することはないように思う。
問題は、それを明確に教えていない本やドキュメントのほう。
0983デフォルトの名無しさん2009/09/16(水) 14:06:39
問題は

hoge というインスタンスメソッドが定義されているとき、 hoge(123) とすると hoge メソッドに 123 が渡される
hoge! というインスタンスメソッドが定義されているとき、 hoge!(123) とすると hoge! メソッドに 123 が渡される
hoge? というインスタンスメソッドが定義されているとき、 hoge?(123) とすると hoge? メソッドに 123 が渡される
[] というインスタンスメソッドが定義されているとき、 [](123) とすると [] メソッドに 123 が渡される
[]= というインスタンスメソッドが定義されているとき、 []=(123) とすると []= メソッドに 123 が渡される

とここまで来ておきながら

hoge= というインスタンスメソッドが定義されているとき、 hoge=(123) とするとローカル変数 hoge に 123 が代入される

になること
0984デフォルトの名無しさん2009/09/16(水) 14:38:32
着眼点はおもしろいな。
ただ、それは
・代入のほうが優先される
というルールで簡単に説明できるんじゃね?
これなら十分わかりやすい。
0985デフォルトの名無しさん2009/09/16(水) 15:58:47
ルヴィーっておもしろいですか?ルヴィー使ってる友達が、開発者が日本人だから誇らしいと言ってました
0986デフォルトの名無しさん2009/09/16(水) 16:02:12
hoge= が hoge = と書いても動作するのが原因のひとつのような気がしてきた
0987デフォルトの名無しさん2009/09/16(水) 16:17:07
クラス変数が@@var
インスタンス変数が@var
なんだから
ローカル変数にも命名規約を作ればよかっただけ
#varとか

設計者の脳みそが足りなかった
0988デフォルトの名無しさん2009/09/16(水) 16:18:50
つまり認識の順番が逆なんだよ

 ・ obj.hoge = や obj.hoge= とあったとき、それは必ず obj のメソッド hoge=() である
 ・ hoge = や hoge= とあったとき、それは必ず変数 hoge への代入である
 ・ 末尾に = がついたメソッドはいわゆる関数形式では呼べないので諦めろ

こう覚える
0989デフォルトの名無しさん2009/09/16(水) 17:00:32
ルールの一貫性なんかより普段書いてて使いやすいかのほうが重要
0990デフォルトの名無しさん2009/09/16(水) 17:14:11
冗長な接頭辞なんかいらんつーの
0991デフォルトの名無しさん2009/09/16(水) 17:57:10
>>989
ふだん書いてて使いやすいように、一貫したルールが必要なんだろ
マニュアル見ながらだと書きやすいが暗記しにくいルールなんて糞だ
0992デフォルトの名無しさん2009/09/16(水) 18:25:45
> マニュアル見ながらだと書きやすいが暗記しにくいルールなんて糞だ

Perl の $ と @ が脳裏をよぎったw
0993デフォルトの名無しさん2009/09/16(水) 18:31:03
ruby厨無理スンナ
0994デフォルトの名無しさん2009/09/16(水) 18:55:03
>>982や988で十分わかりやすいと思うけどな。
アンチさんたちは何が不満なのかな。
0995デフォルトの名無しさん2009/09/16(水) 19:24:17
>>994
アンチってどれよ
0996デフォルトの名無しさん2009/09/16(水) 20:57:58
これどっちなんだっけ、と迷うようなコードは書かないのが定石だろうに
0997デフォルトの名無しさん2009/09/16(水) 21:01:30
今更そんな当たり前のこと言われても
0998デフォルトの名無しさん2009/09/16(水) 23:18:44
雑魚乙ということで埋め
0999デフォルトの名無しさん2009/09/16(水) 23:19:59
雑魚乙ということで埋め
1000デフォルトの名無しさん2009/09/16(水) 23:21:35
雑魚乙ということで埋め
10011001Over 1000Thread
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。
レス数が1000を超えています。これ以上書き込みはできません。