Ruby 初心者スレッド Part 30
レス数が950を超えています。1000を超えると書き込みができなくなります。
0001デフォルトの名無しさん
2009/08/08(土) 08:21:23★注意★ 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を読め」でいいので、叩かない&怖がらせない。
・わけわかな質問にもエスパー発揮で。できれば質問の仕方を教えるぐらいで。
・自信がない回答ならその旨表明すること。誤った回答は初心者じゃ見抜けない。
0894デフォルトの名無しさん
2009/09/11(金) 22:00:330895デフォルトの名無しさん
2009/09/11(金) 22:03:58ruby pdfでググると色々出てくるので好きに選べばいいじゃない
0896デフォルトの名無しさん
2009/09/12(土) 07:51:58ぶっちゃけ、基本ただのテキストファイル。仕様どおりに作ればいい。
適当に一部分だけgzipかけてみたりフォント埋め込んでみたり暗号化してみたり
してる部分もあるが、それは全部付加的なものだし。
現実的には、>>895。RubyならHaruでいいんじゃね?
0897デフォルトの名無しさん
2009/09/12(土) 08:33:37ハイハイ、マルチポスト、マルチポスト
Rubyでpdfファイルを読み込む方法 -OKWave
http://okwave.jp/qa5281984.html
こっちで、解決したらあっちのも答え書いとけよ
0898デフォルトの名無しさん
2009/09/12(土) 09:15:54簡単にできるのならやってみようかな
0899デフォルトの名無しさん
2009/09/12(土) 09:35:10PDFをプレーンテキストにする外部プログラムにファイルを渡して
標準入力から受け取って文字列にしてるだけ
0900デフォルトの名無しさん
2009/09/12(土) 15:15:55def hoge arg
p arg
end
hoge( :a => 1, :b => 2 ) #=> {:a=>1, :b=>2}
hoge( {:a => 1, :b => 2} ) #=> {:a=>1, :b=>2}
0901デフォルトの名無しさん
2009/09/12(土) 15:24:48{}はHashを意味している。
メソッド引数の最後のものがHashである場合に限り、{}を省いてよい。
0902デフォルトの名無しさん
2009/09/12(土) 15:28:06そうなんですか。
�d
0903デフォルトの名無しさん
2009/09/12(土) 16:44:490904デフォルトの名無しさん
2009/09/12(土) 17:03:010905デフォルトの名無しさん
2009/09/12(土) 19:24:560906デフォルトの名無しさん
2009/09/12(土) 21:54:36何を以って強さとするかによる
0907デフォルトの名無しさん
2009/09/12(土) 22:09:19書きやすさ
読みやすさ
インストールのしやすさ
ライブラリの使い勝手
リファクタリングの効率
配布
どれをとっても(ry
0908デフォルトの名無しさん
2009/09/12(土) 22:43:510909デフォルトの名無しさん
2009/09/12(土) 23:27:500910デフォルトの名無しさん
2009/09/13(日) 00:19:22pythonスレではまじめにレスするかスルーされるケースが多い
よってruby埼京
0911デフォルトの名無しさん
2009/09/13(日) 00:23:54そんなに寂しいのか彼らは
0912デフォルトの名無しさん
2009/09/13(日) 02:08:10おまえはボケのセンスがないんだな
0913デフォルトの名無しさん
2009/09/13(日) 12:39:10(@@connections ||= []) << self
上記のコードの
@@がクラス変数, << が配列への要素の追記ということはわかったのですが
||= の記号の意味がうまく調べられませんでした
どなたか教えていただけないでしょうか?
0914デフォルトの名無しさん
2009/09/13(日) 12:42:560915デフォルトの名無しさん
2009/09/13(日) 13:08:12||=は左辺がnil、falseでないときは何もしない
もしnil、falseなら右辺を代入する。
0916デフォルトの名無しさん
2009/09/13(日) 13:29:01http://doc.okkez.net/static/187/doc/spec=2foperator.html
0917デフォルトの名無しさん
2009/09/13(日) 14:10:48foo ||= []
は
foo = [] unless foo
とおなじ。
(foo ||= []) << "aaa"
は
foo = [] unless foo
foo << "aaa"
とだいたい同じ。
0918デフォルトの名無しさん
2009/09/13(日) 15:18:56これはこれで面倒な話でありましてですな
0919デフォルトの名無しさん
2009/09/13(日) 15:34:47irb> (p "ok") if foo
NameError: undefined local variable or method `foo' for main :Object
from (irb):1
from :0
がエラーで
irb> (foo = "ok") if foo
nil
が OK というのは不条理っちゃ不条理ではある
ちなみに (foo = "ok") if foo のあと、 foo は nil を返す
0920デフォルトの名無しさん
2009/09/13(日) 15:42:16どういう基準で分かれてるんだろう?
0921デフォルトの名無しさん
2009/09/13(日) 16:11:24FAQ にもあるんだが、ローカル変数は、構文解析で代入が見つかるかどうかだけが鍵
実際に(いつ)実行されるかどうかは関係がない
if false
foo = "OK"
end
foo
上記は NameError を起こさないが、以下は foo が NameError を起こす
for e in [1, 2 ,3]
if e == 2 then
foo
else
foo = "OK"
end
end
動作は同一なはずの unless で 代入記述の順番を変えると NameError は起こらない
for 構造はスコープを作らないことに注意
for e in [1, 2 ,3]
unless e == 2 then
foo = "OK"
else
foo
end
end
0922デフォルトの名無しさん
2009/09/13(日) 16:15:42ttp://www.ruby-lang.org/ja/man/html/FAQ_CAD1BFF4A1A2C4EABFF4A1A2B0FABFF4.html#a2.2e3.20.a5.ed.a1.bc.a5.ab.a5.eb.ca.d1.bf.f4.a4.cf.a4.a4.a4.c4.bb.b2.be.c8.b2.c4.c7.bd.a4.cb.a4.ca.a4.eb.a4.ce.a4.c7.a4.b7.a4.e7.a4.a6.a4.ab
長い長すぎる
FAQでは昔ながらに「nil で初期化しとけ」と書いてあるが、
こんな繰り返しのスコープを意図的に利用するスクリプトを書くことのほうがヤバい兆候であることがわかってる
素直に他の方法を考えるのがよい
そもそも一般的な each ではスコープが毎回切れるからこれの再現すらできないしな
0923デフォルトの名無しさん
2009/09/13(日) 16:16:02気持ち悪くないのかな。それとも、別に実装の都合ではなくてポリシーなのか?
0924デフォルトの名無しさん
2009/09/13(日) 16:31:24ブロックでスコープをわけないようにするという話もあったりするので、
遠い未来の2.0あたりでは>>921の例も動くようになるかも。
0925デフォルトの名無しさん
2009/09/13(日) 16:41:100926913
2009/09/13(日) 16:46:38ご丁寧にありがとうございます。
ソース読んでいてここだけわからなくて困っていたのですが助かりました。
0927デフォルトの名無しさん
2009/09/13(日) 16:48:29if ARGV
opt1 = ...
end
opt1_runner(opt1) if defined?(opt1)
これが期待通り動作しないということなんだぜ
たかがローカル変数で
opt1 = nil
if ARGV
opt1 = ...
end
opt1_runner(opt1) if opt1
とか書かなければならないのは流石にバカっぽい
0928デフォルトの名無しさん
2009/09/13(日) 17:13:360929デフォルトの名無しさん
2009/09/13(日) 17:15:13いわんとすることはわかるが
0930デフォルトの名無しさん
2009/09/13(日) 17:18:18ローカル変数を初期化不要にしてしまうと、フィールド変数を参照してるつもりでスペルミスしてもエラーにならなくなる。
あらゆる場所で意図しないローカル変数が勝手に生成される可能性があるわけで何とも気持ち悪い。
フィールドはオブジェクトの属性という意味合いから初期値があるのは自然だけど、
ローカル変数はちょっと値を保存しておく場所って意味合いしかないから、ソースコードを簡略化するために初期値を設けるってのも設計上美しくない
0931デフォルトの名無しさん
2009/09/13(日) 17:37:53下記のように@flagを判別して
@flagがtrueの場合, testのputs "test"が実行され
@flagがnilの場合,testを中断させputsは実行されない
という処理を書きたいのですが可能でしょうか?
flag_ok?でfalseを返してもいいのですが、
test2,test3と他にも最初にフラグをチェックして@flagがnilの場合、処理を中断したいメソッドが複数あるので、シンプルに書く方法を模索してます
@flag = nil
def test
flag_ok?
puts "test"
end
def test2
flag_ok?
puts "test2"
end
def flag_ok?
if @flag
return true
else
return "testの実行を中断させるなにか"
end
end
0932デフォルトの名無しさん
2009/09/13(日) 17:45:10def test
return if @flag
puts "test"
end
def test2
return if @flag
puts "test2"
end
これじゃなんかダメなん
0933デフォルトの名無しさん
2009/09/13(日) 17:51:15条件逆
0934931
2009/09/13(日) 19:08:11ありがとうございます参考に直してみました。
ちょっとエラー時に処理をいれたかったのと
うまいこと1行で書きたかったのですが
すっかり if,unlessのこの書き方を失念してました
@flag = nil
def test
return unless flag_ok?
puts "test"
end
def flag_ok?
if @flag
return true
else
puts "処理"
return false
end
end
0935デフォルトの名無しさん
2009/09/13(日) 21:25:210936デフォルトの名無しさん
2009/09/13(日) 21:32:13@hoge = 1234
の@hogeのこと。
Rubyだとインスタンス変数かな?
フィールド変数はJava用語だったかも?Delphiでも聞いたな。
C++だとメンバ変数だっけか。
0937デフォルトの名無しさん
2009/09/13(日) 21:33:51Rubyで言うインスタンス変数
逆か、他の言語で言うフィールド変数はRubyではインスタンス変数で扱う
0938デフォルトの名無しさん
2009/09/13(日) 22:56:490939デフォルトの名無しさん
2009/09/13(日) 23:24:18じゃないぞ
フィールド=メンバ変数=インスタンス変数&クラス変数
が正しい
0940デフォルトの名無しさん
2009/09/14(月) 10:52:05class A
class B
class C
end; end; end
A B C を模したモジュール M があります
module M
module A; def hoge; end
module B; def hoge; end
module C; def hoge; end
end; end; end; end
で、M を適度に include して A.new.hoge も B.new.hoge も C.new.hoge も有効にしたいんですが、
次のような書き方しかできないような気がします
class A; include M::A
class B; include M::A::B
class C; include M::A::B::C
end; end; end
なんというかこー、せっかく模したので「一発」でできるようにしたいのですが、なんかうまい方法ないですか
0941デフォルトの名無しさん
2009/09/14(月) 11:04:180942デフォルトの名無しさん
2009/09/14(月) 13:13:31def get_module_object(name)
mod = Object
name.split(/::/).each do |s|
mod = mod.const_get(s) or raise NameError.new("#{name}: not found.")
end
return mod
end
get_module_object('M::A::B::C')
def include_recursively(klass, namespace)
mod = get_module_object("#{namespace.name}::#{klass.name}")
klass.class_eval { include(mod) } if mod
for name in klass.constants
c = klass.const_get(name)
include_recursively(c, namespace) if c.is_a?(Class)
end
nil
end
include_recursively(A, M::A)
p A.ancestors #=> M::A が含まれている
p A::B.ancestors #=> M::A::B が含まれている
p A::B::C.ancestors #=> M::A::B::C が含まれている
実行効率はあんまりよくないけど許して。
0943デフォルトの名無しさん
2009/09/15(火) 01:18:30ググりましたが、断片的に
ttp://www.rubyist.net/~matz/20070130.html
ttp://www.javaeye.com/topic/50494(中国語)
があるくらいです。
何か役に立ちそうなサイトがありましたらお教え下さい。
0944デフォルトの名無しさん
2009/09/15(火) 09:29:00昔のテープメディアみたいでなんかヤなんだけど
0945デフォルトの名無しさん
2009/09/15(火) 09:50:31IO自体がテープメディアみたいなもんなんだけどw
0946デフォルトの名無しさん
2009/09/15(火) 10:21:36同名モジュールの include で疑問があったことを思い出した
module A
def hoge; B.new; end
end
module B; end
class A; include A; end
classB; include B; end
これで、A.hoge すると モジュール B の new メソッド(無論ない)を呼ぼうとするんだよ
全く以って書いてある通りに動いてるだけなんでございまするが、
module A を作る時点で、include 先から見た B クラスを使うように指定することはできんもんかね
0947デフォルトの名無しさん
2009/09/15(火) 10:42:03できない…と思う
include したらたまたま同名の自作クラス B があったためにモジュールが動作しませんとかモジュールの意味ねえよ
モジュール内部で呼ぶ B はモジュールが定義されたときに(モジュール内部に)存在する B だ
:: で始まる「フルパス」で書くしかないな
include されるクラス名が不定なのならお隣クラス B を呼ぶことはそもそもできないので諦めるべし
0948デフォルトの名無しさん
2009/09/15(火) 10:47:53module A
def hoge ; self.class.const_get(:B).new ; end
:
0949デフォルトの名無しさん
2009/09/15(火) 11:17:23擬似コードですが、こんな感じで書けたらと思ってます
if nkfがrequireされていたら; ・・・
elsif uconvがrequireされていたら; ・・・; end
現在はbeginブロックに入れてNameErrorで判断しています
0950デフォルトの名無しさん
2009/09/15(火) 11:49:19そのライブラリが何か定義するなら
defined? NKF
とか。
あと、$LOADED_FEATURES ($") というグローバル変数もあるが、
ファイル名べったり依存になるのであまり推奨したくないな。
0951デフォルトの名無しさん
2009/09/15(火) 12:09:440953デフォルトの名無しさん
2009/09/15(火) 12:38:57requireされてるかわからないということは自分以外がrequireしたってことだから
ファイル名を知らないし知る必要もないと思う
require 'lib/example'
require './lib/example'
$LOAD_PATH << "lib/"
require 'example'
とりあえず実際問題として、$"ではこれらが区別されるから(requireも二重ロードをする)
>>950のようなduck type的アプローチのほうがよいかと
0954デフォルトの名無しさん
2009/09/15(火) 13:12:18実装の違いは別として機能的には。
0955デフォルトの名無しさん
2009/09/15(火) 13:22:040956デフォルトの名無しさん
2009/09/15(火) 13:44:37だいたい合ってる
あえて区別するなら、ポリモーフィズムはクラスC1とC2に何かしらの関係性が産まれる
(スーパークラスが同じとか、インターフェイス/モジュールに同じモノを使うとか)
ダックタイプはメソッドに応答するだけでいい
「共通であるから同じに扱う」と「同じに扱えたから共通だと見なす」という感じ
0957デフォルトの名無しさん
2009/09/15(火) 13:48:21たぶん、関係性が産まれている場面でばかり使われていたから
関係性がないことを強調した言葉として派生させたのがダックタイプなんじゃないかな
0958デフォルトの名無しさん
2009/09/15(火) 15:42:31あと、require だと拡張子が省けるが、$" の中には拡張子込みで
入るので、実装を気にする必要も出てくる。
0959デフォルトの名無しさん
2009/09/15(火) 16:58:310960デフォルトの名無しさん
2009/09/15(火) 17:49:110961デフォルトの名無しさん
2009/09/15(火) 17:56:21self.class::B.new
0962デフォルトの名無しさん
2009/09/15(火) 19:54:22それだと A::B と解釈されるからダメ
0963デフォルトの名無しさん
2009/09/15(火) 20:01:34えーそれってMRI(YARV)? それともRubyCocoaとか?
0964デフォルトの名無しさん
2009/09/15(火) 20:11:43module 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$ 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基本的にシステム固有のsuffixが使われる。
例外は、ライブラリにlibなどのprefixをつける慣習がないWindows等DOSISH系。
たとえば、libiconvのiconv.dllと拡張ライブラリのiconv.dllが区別つかなく
なるという事態を避けるため、後者を.soにしている。
0968デフォルトの名無しさん
2009/09/15(火) 22:48:23なんで enumerator.bundle じゃないんだろう。
0969デフォルトの名無しさん
2009/09/16(水) 02:31:22実際に探索したわけでもないパスだから。
0970デフォルトの名無しさん
2009/09/16(水) 04:32:190971デフォルトの名無しさん
2009/09/16(水) 04:47:18なんでpythonじゃなくてルビーなの?
開発者が日本人だから?愛国心ってやつ?ねえ?
0972デフォルトの名無しさん
2009/09/16(水) 05:42:560973デフォルトの名無しさん
2009/09/16(水) 06:59:09煽りに使えそうな反論が出たらpythonスレに張り付けに行くんだろ?
0974デフォルトの名無しさん
2009/09/16(水) 08:11:470975デフォルトの名無しさん
2009/09/16(水) 09:57:02def 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:110977デフォルトの名無しさん
2009/09/16(水) 10:30:57代入の形したメソッドがある場合はどっち使うのか注意
0978デフォルトの名無しさん
2009/09/16(水) 10:35:22決定されるのは自然な発想では
ただ確かに紛らわしいから、結局
>このへんの動作に依存したスクリプト作るのやめれ
じゃなかろうか
0979デフォルトの名無しさん
2009/09/16(水) 10:41:58hoge= というインスタンスメソッドがあっても、hoge=Array.new はローカル変数への代入だ
= つきのインスタンスメソッドを呼びたい場合はレシーバが必須になる
この場合は self をつけて self.hoge=Array.new だな
これに def hoge; @hogeを処理して返す; end が加わってると混迷を増す
0980デフォルトの名無しさん
2009/09/16(水) 12:00:210981デフォルトの名無しさん
2009/09/16(水) 13:23:01呼び出しはそれでいいんだけど、>>977も言うようにキモは代入でしょ
ローカル変数とインスタンスメソッドに同じ名前さえ付けなければ
この手の問題は起きないと思ってる人はわりといるはず、つーか俺
>>980
存在するローカル変数と存在するインスタンスメソッドなら同意
まだ存在しないローカル変数と存在するインスタンスメソッドだったら、存在する方が優先に思える
「代入もメソッド呼び出しである」と考えると
変数hogeがないときにself.hogeが呼ばれる動作と対称的ではないのが違和感の原因
「疑わしきはローカル変数と見なす」も理解はできるけどね
0982デフォルトの名無しさん
2009/09/16(水) 13:57:45それは仕方ない。そういうもんです、慣れてくださいとお願いするしかない。
ただまあ、代入に関して言えば、
・foo = 123 は変数への代入
・obj.foo = 123 は setter メソッドの呼び出し
というルールが分かっていれば、そう混乱することはないように思う。
問題は、それを明確に教えていない本やドキュメントのほう。
0983デフォルトの名無しさん
2009/09/16(水) 14:06:39hoge というインスタンスメソッドが定義されているとき、 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:470986デフォルトの名無しさん
2009/09/16(水) 16:02:120987デフォルトの名無しさん
2009/09/16(水) 16:17:07インスタンス変数が@var
なんだから
ローカル変数にも命名規約を作ればよかっただけ
#varとか
設計者の脳みそが足りなかった
0988デフォルトの名無しさん
2009/09/16(水) 16:18:50・ obj.hoge = や obj.hoge= とあったとき、それは必ず obj のメソッド hoge=() である
・ hoge = や hoge= とあったとき、それは必ず変数 hoge への代入である
・ 末尾に = がついたメソッドはいわゆる関数形式では呼べないので諦めろ
こう覚える
0989デフォルトの名無しさん
2009/09/16(水) 17:00:320990デフォルトの名無しさん
2009/09/16(水) 17:14:110991デフォルトの名無しさん
2009/09/16(水) 17:57:10ふだん書いてて使いやすいように、一貫したルールが必要なんだろ
マニュアル見ながらだと書きやすいが暗記しにくいルールなんて糞だ
0992デフォルトの名無しさん
2009/09/16(水) 18:25:45Perl の $ と @ が脳裏をよぎったw
0993デフォルトの名無しさん
2009/09/16(水) 18:31:03レス数が950を超えています。1000を超えると書き込みができなくなります。