Ruby 初心者スレッド Part 41
■ このスレッドは過去ログ倉庫に格納されています
0001京 ◆SsSSsSsSSs
2011/02/10(木) 13:47:51★注意★ Ruby 1.9.2 は初心者には若干時期早尚です。初心者には Ruby 1.8.7 を強くお勧めします。
文字エンコーディング等の外部基礎知識が必要な上、不完全対応の第三者ライブラリでの問題の切り分けが手間です。
迷う点の少ない1.8.7に習熟→おもむろに1.9.2の変更点のみ重点学習、とすればスムーズに移行できるでしょう。
関連スレや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を読め」でいいので、叩かない&怖がらせない。
・わけわかな質問にもエスパー発揮で。できれば質問の仕方を教えるぐらいで。
・自信がない回答ならその旨表明すること。誤った回答は初心者じゃ見抜けない。
0048デフォルトの名無しさん
2011/02/17(木) 21:12:14被らないバージョンのRubyも存在するが、互換性の問題でこれに頼った記述は全く勧められないので忘れてくれ
a.inject{|x, y| x + y}
とか書くのが一応回答
0049デフォルトの名無しさん
2011/02/17(木) 21:15:50そうなんだよなあ…
何がめんどくさいって、ここが問題で1.8ではうまく動作しないということを見つけるまでが果てしなくめんどくさい
0050デフォルトの名無しさん
2011/02/17(木) 22:01:07「a」.inject {|「a」, b| 「a」 + b}
上のaは全部同じオブジェクトなのでループしたときにaが上書きされる
0051デフォルトの名無しさん
2011/02/17(木) 22:04:25&:foo と &method(:foo)は見た目似ているけど
仕組みは全然違うから混同しちゃダメ。
後者はあくまでもself.method(:foo)のことで
self.foo をMethod Objectとして取り出しているので
{|x| self.foo x}と同じ意味になる。
&:foo の方はSymbol#to_procによってProc Objectに変換されるので
実際には :foo.to_proc がブロックとして渡されてる。
Symbol#to_procってのは
class Symbol
def to_proc
proc{|obj, *args| obj.send(self, *args)}
end
end
な感じの定義なわけでつまり:foo.to_procは
proc{|obj, *args| obj.send(:foo, *args)}
ちょっと書き換えると
proc{|obj, *args| obj.foo(*args)}
となる。 つまり1つ目の引数のメソッドfooに残りの引数を引き渡す感じ
{|x| x.foo }とか {|x, y| x.foo y }と同じ動作になる
0052デフォルトの名無しさん
2011/02/17(木) 22:32:50&method(:foo)のほうは{|*args| self.foo *args}かな
しかし↓この説明でそこまで分かる人いるのか?
Symbol#to_proc -> Proc
self に対応する Proc オブジェクトを返します。
(1..3).collect(&:to_s) #=> ["1", "2", "3"]
(1..3).inject(&:+) #=> 6
0053デフォルトの名無しさん
2011/02/18(金) 00:15:261.9からは被らずにちゃんと遮蔽するよ
ついでに実験的仕様でブロックローカル変数を作れるようにもなった
a,b = :a,:b
[:foo].each do |a;b| # ;の後ろにブロックローカル変数を宣言できるぞ
b=:bar
p [a,b] #=> [:foo,:bar]
end
p [a,b] #=> [:a,:b]
1.8までは何でも書けたらしいね
a = [[:a,:b,:c]]
a.each{|a,$b,@c|}
p [a,$b,@c] #=> [:a,:b,:c]
>>50
ちょっとちがうんじゃね?
オブジェクトうんぬんじゃなくて、ローカル変数のスコープの話だと思うんだけど
0054デフォルトの名無しさん
2011/02/18(金) 00:19:29>互換性の問題でこれに頼った記述は全く勧められないので忘れてくれ
0055デフォルトの名無しさん
2011/02/18(金) 00:35:39っていうか 1.8 が消え去るまで ruby やる気が失せた...
ありえないだろJK.
005647
2011/02/18(金) 00:38:000057デフォルトの名無しさん
2011/02/18(金) 01:31:00なければ新たな変数の定義となる(ただし1.9系のブロック引数は常に後者)
宣言無しで変数を使えますよ系言語の欠点
外側に同名の変数があっても新たな変数を定義できるような構文が欲しくなることがある
0058デフォルトの名無しさん
2011/02/18(金) 02:05:13ブロック等の一番せまいスコープならまだ許せる
i、jは例外だと思うけど、それでもスコープ狭くするべき
テンポラリでないなら変数にちゃんとした名前つけろ
0059デフォルトの名無しさん
2011/02/18(金) 02:09:22以下スタック食いつぶすまで続く
0060デフォルトの名無しさん
2011/02/18(金) 02:10:55x = 1 [2,3].each {|y;x| x = y }
こうすると x は 1 のままになる.
0061デフォルトの名無しさん
2011/02/18(金) 02:25:35x = 1
[2,3].each {|y;x| x = y }
こうすると x は 1 のままになる.
0062デフォルトの名無しさん
2011/02/18(金) 02:59:54x = 1
[2,3].each {|y;x| x = y }
こうすると x は 1 のままになる.
0063デフォルトの名無しさん
2011/02/18(金) 03:02:40x = 1
[2,3].each {|y;x| x = y }
こうすると x は 1 のままになる.
0064デフォルトの名無しさん
2011/02/18(金) 03:20:10x = 1
[2,3].each {|y;x| x = y }
こうすると x は 1 のままになる.
0065デフォルトの名無しさん
2011/02/18(金) 08:54:01def local &block
local_vars = eval("local_variables", block)
name_of_vals_arr = "__local_vals"
loop do
break if local_vars.all?{|var| var != name_of_vals_arr }
name_of_vals_arr += "_"
end
eval("#{name_of_vals_arr} = [#{local_vars.join(',')}]", block)
yield
local_vars.each{|var| eval(var + " = #{name_of_vals_arr}.shift", block) }
end
i = 1
j = 2
puts "i = #{i}, j = #{j}" # => i = 1, j = 2
local do
i = "a"
j = "b"
puts "i = #{i}, j = #{j}" # => i = a, j = b
end
puts "i = #{i}, j = #{j}" # => i = 1, j = 2
0066デフォルトの名無しさん
2011/02/18(金) 19:29:03ファイルポインタを動かしても write を使うと後ろに書き込まれてしまいます。
よろしくお願いします。
0067デフォルトの名無しさん
2011/02/18(金) 20:10:25いわゆる挿入モードは一発ではできません、が回答だと思う…
そーゆーもんなので、どうしようもない
irb> File.open('a','w'){|f| f.puts "111\n222\n333\n444"}
irb> puts File.open('a'){|f| f.read}
111
222
333
444
irb> File.open('a','r+'){|f| body = f.read; f.rewind; f.puts "000\n#{body}"}
irb> puts File.open('a'){|f| f.read}
000
111
222
333
444
0068デフォルトの名無しさん
2011/02/18(金) 20:35:31http://code.google.com/codejam/japan
rubyでも参加できるらしいぞ。
0069デフォルトの名無しさん
2011/02/18(金) 20:58:300070デフォルトの名無しさん
2011/02/19(土) 12:34:33}
end
}
end
end
end
↑はちょっと大げさだけど混在が気持ち悪い。
みな賛同してますか
0071デフォルトの名無しさん
2011/02/19(土) 12:35:550072デフォルトの名無しさん
2011/02/19(土) 12:52:130073デフォルトの名無しさん
2011/02/19(土) 15:20:15あまり気にしてない
ちょっと慣れると、エンドという英単語を読んでるわけではない、という境地になる
ただのヨコ長のブロック終端記号だ
0074デフォルトの名無しさん
2011/02/19(土) 15:43:09>混在が気持ち悪い。
混在は気にしないかな。end自体は気にするけど。
0075デフォルトの名無しさん
2011/02/19(土) 17:58:52リソース管理や大域脱出のブロックはブレースを使って目立たせる
コーディングルールもあったはず
0076デフォルトの名無しさん
2011/02/19(土) 23:28:37.73参考にさせていただきます
0077デフォルトの名無しさん
2011/02/20(日) 07:25:41.22ドラグ&ドロップしたときの実行パスを取得するには、どうすればいいのでしょうか?
よろしくお願いします。
プログラムを通常実行したなら、File.expand_path(__FILE__)でパスが取れるのですが、
ドラグ&ドロップ時には、File.expand_path(__FILE__)の中身が、
C:/Documents and Settings/ユーザー名/実行ファイル名.rb
となってしまいます。
0078デフォルトの名無しさん
2011/02/20(日) 07:44:55.62期待通りだけど何がマズイ?
0079デフォルトの名無しさん
2011/02/20(日) 07:46:08.87聞き方がおかしかった。どういう値になるのを期待している?
008077
2011/02/20(日) 08:03:45.59>聞き方がおかしかった。どういう値になるのを期待している?
c:\temp\program.exe
の上にファイルをドラッグしたら、c:\tempのパスが取得できることを期待しています。
(プログラム自体は、program.rbをexerbでprogram.exeに変換しています)
できれば「program.exeへのショートカット」上にドラッグしたとしても、
元のc:\temp\program.exeの実行パスを取得したいです。
0081デフォルトの名無しさん
2011/02/20(日) 10:08:07.34ttp://exerb.sourceforge.jp/man/doc/class.ja.html
0083デフォルトの名無しさん
2011/02/20(日) 23:24:10.74Python に乗り換えた
0084デフォルトの名無しさん
2011/02/21(月) 08:00:25.78ファイルの中身がWindows-31Jのテキストファイルで正規表現を使うにはどうしたら良いの?
# coding:utf-8 と書くとファイルは開けるけど正規表現でエラー
# coding:Windows-31Jと書くとファイル名が文字化けして開けず
0085デフォルトの名無しさん
2011/02/21(月) 08:09:36.27マジックコメントにはソースファイルの文字エンコーディングを記述する
openに渡すファイルパス名のStringオブジェクトの文字エンコーディングをUTF-8にして
マッチに使う正規表現の文字エンコーディングをWindows-31Jにすればよかんべ
Ruby1.9はぜんぶ別個にできるぞ
0086デフォルトの名無しさん
2011/02/21(月) 08:50:12.61ばらばらに指定できるぞ。
0087デフォルトの名無しさん
2011/02/21(月) 10:32:40.65>ファイルの中身がWindows-31Jのテキストファイルで正規表現を使うにはどうしたら良いの?
こっちを優先して、コードはwindows-31jで書く。
ほんで、ファイル名を表す文字列はunicodeに変換してやる。
0088デフォルトの名無しさん
2011/02/21(月) 10:49:29.190089デフォルトの名無しさん
2011/02/21(月) 14:13:01.980090デフォルトの名無しさん
2011/02/21(月) 15:09:28.210091デフォルトの名無しさん
2011/02/21(月) 18:01:35.10ARGVはダメっぽい?
009284
2011/02/21(月) 20:18:15.66あと、Encoding.default_internal がよく分かりません。
指定しておくと読み込んだ内容がその文字コードに変換されるのかと思ったんですが……
0093デフォルトの名無しさん
2011/02/22(火) 00:51:00.99ちょっと遅レスだが
require 'Win32API'
rubypath = "\0"*2048
Win32API.new('kernel32', 'GetModuleFileName', %w(i p i), 'i').call(0,rubypath,rubypath.size)
rubypath.rstrip!
p rubypath
0094デフォルトの名無しさん
2011/02/22(火) 13:37:28.410095デフォルトの名無しさん
2011/02/22(火) 15:59:04.40むしろ、昔から使ってるひと向けに
0096デフォルトの名無しさん
2011/02/22(火) 16:05:11.220097デフォルトの名無しさん
2011/02/22(火) 16:30:55.980098デフォルトの名無しさん
2011/02/22(火) 16:40:10.290099デフォルトの名無しさん
2011/02/22(火) 17:26:16.31リアル中2、Ruby最年少コミッタに就任【増田(@maskin)真樹】
http://techwave.jp/archives/51599766.html
0100デフォルトの名無しさん
2011/02/22(火) 17:34:49.250101デフォルトの名無しさん
2011/02/22(火) 19:34:27.07手元にあるたのしいRubyには全く載っていませんでした
0102デフォルトの名無しさん
2011/02/22(火) 20:00:56.10とかいうようなシロモノなので結構厳しい
0103デフォルトの名無しさん
2011/02/22(火) 21:58:19.20あったらいいね
0104デフォルトの名無しさん
2011/02/22(火) 22:05:43.440105デフォルトの名無しさん
2011/02/22(火) 22:12:17.94JavaのConcurrentパッケージとか日本語訳もされてる
並列処理関連のJava本を書いてたような
0106デフォルトの名無しさん
2011/02/23(水) 00:34:22.12Doug Leaはダグリーって呼ぶのだろうか……?
0107デフォルトの名無しさん
2011/02/23(水) 00:48:35.760108デフォルトの名無しさん
2011/02/23(水) 01:54:16.68普通に英語読みしたらダグリーだけど
実は英語圏出身じゃなくて読み方が微妙に違うとか何とかあるのかい?
0109デフォルトの名無しさん
2011/02/23(水) 02:04:44.44DougはDouglas の愛称のダグなので確定として、
Leaのほうは、英語読みすればリーかな、程度だなぁ。
ま、実際彼の名のカタカナ書きはダグ・リーが一般的。
0110デフォルトの名無しさん
2011/02/23(水) 06:44:52.71「ここはRubyで書くかな」って判断する基準って何かありますか?
0111デフォルトの名無しさん
2011/02/23(水) 06:54:51.44そんなものはない
Rubyで書きにくい・動かしにくい・指定されてないから他の言語で書く
0112デフォルトの名無しさん
2011/02/23(水) 07:53:36.190113デフォルトの名無しさん
2011/02/23(水) 09:02:46.90マクロならLisp。
0114デフォルトの名無しさん
2011/02/23(水) 10:07:20.76再帰が多いならScheme
GUI扱うならJava
ライブラリ開発や、OSのAPIとか使いまくるならC
0115デフォルトの名無しさん
2011/02/23(水) 16:06:26.92attr_accessor :x, :y, :z
def setp
@x = "@x"
self.y = "self.y"
z = "z"
end
def say
print x,' ',y,' ',z
puts
end
end
本を読みながらこんなの書いて実験してみたけど・・・
@変数とself.変数って同じ挙動だから好きな方使っていいんですよね?
高度な使い方すると違うかもしれないけど、そこまで到達してないから違いがわかんない
0116デフォルトの名無しさん
2011/02/23(水) 16:55:45.56puts "this number is #{var}" => this number is 1
puts "this number is" + var => エラー
この仕様は何か意図があるんでしょうか。。
fixnumを自動でstringに変換してくれてもいいのに、って思ってしまいます。
譲って後者をエラーにするのであれば前者もエラーにすべきとも思います。
rubyistの方のどのように考えているのですか?
0117デフォルトの名無しさん
2011/02/23(水) 17:09:35.97ぶっちゃけ最初はよくわからないと思う
クラス定義の中から使うなら @変数 を使う、
クラス定義の外から使うならメソッド使う、でしばらくいっと毛
0118デフォルトの名無しさん
2011/02/23(水) 17:30:30.29var = 1
puts "this number is #{var}" # varがto_sされるのは誰が見ても明らか
puts "this number is " + var # これも明らか
other_var + var # どうだっけ
0119デフォルトの名無しさん
2011/02/23(水) 17:32:18.510120デフォルトの名無しさん
2011/02/23(水) 17:37:21.52思いっきり大前提として、「+は表示用連結記号ではない」というのをしっかり認識して欲しいと思う
puts "STRING" + var は "STRING" + var つまり "STRING".+(var) の返り値を puts に渡してるに過ぎない
表示するときに便利とかどうでもよくて、String クラスのインスタンスメソッド + の処理結果を利用している
で、String#+ の引数に String クラスのオブジェクト以外がきたとき、どうするのが本来好ましいか
・ 引数のオブジェクトの to_s メソッドを勝手に試して、自身と連結して返す ← まちがい
・ 引数のオブジェクトが文字列と全く同じ動作をする場合にのみ、自身と連結して返す ← せいかい!
ということで、自分と同じ動作をするオブジェクトである場合に限って + で連結を試す
+ の引数になるということは String オブジェクトのメソッドが動作するとみなしてもよいということ
そういう「俺 String オブジェクトのつもりで頑張りますメソッドも作ってきました」という宣言が、to_str メソッド
"#{うめこみ}" で呼ばれる うめこみ#to_s は「オブジェクトを文字列で表現するとこんな感じ」を返す
書いているうちに飽きてきたのでトス
0121デフォルトの名無しさん
2011/02/23(水) 17:42:16.67Stringオブジェクト + foo
は
"ABC#{foo}DEF"
ほど foo を文字列化する意図が明確ではないのでとりあえず例外出して止める、
+ で連結したいなら foo をなんとかして自力で文字列化しろ、というのがいちおう回答ではあるのだが
0122デフォルトの名無しさん
2011/02/23(水) 17:47:51.620123デフォルトの名無しさん
2011/02/23(水) 18:14:52.42irb(main):414:0> require 'self'
Principle of minimum surprise, by Matz
Explicit is better than implicit.
Ruby is far better than P^D
%
0124デフォルトの名無しさん
2011/02/23(水) 18:57:21.91=> 12
こうなってほしいの? 俺は嫌だ。むしろ3になって欲しい
0125デフォルトの名無しさん
2011/02/23(水) 19:02:59.66Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'int' objects
0126デフォルトの名無しさん
2011/02/23(水) 22:17:06.67すでに124が書いているように、"1" + 2 が "12" になるべきか "3" になるべきかは
人によって意見が違う。
そういう、あいまいな解釈ができそうな場合はとりあえずエラーにしておき、
どちらの挙動を意図しているのかを書き手が明示するほうがいいと思う。
"1".to_i + 2
"1" + 2.to_s
またRubyではすでに "x=#{x}" のような埋め込み式が使えるから、
わざわざ "x=" + x を自動変換したいという要求は出ないと思うよ。
0127デフォルトの名無しさん
2011/02/23(水) 22:17:50.61説明が長いよ・・・初心者がそんなの読むわけないじゃん
0128デフォルトの名無しさん
2011/02/23(水) 23:39:41.73アクセサを作らずにやったら違いが解ると思う
0129デフォルトの名無しさん
2011/02/24(木) 00:30:00.56direct variable access と indirect variable access でぐぐって。
どっちを使うかはケースバイケース。
0130116
2011/02/24(木) 02:47:08.45#{うめこみ} と puts "string" + 1
を比較するのではなく、
#{うめこみ} と "string" + 1
を比較しないと駄目、というところで氷解しました。
確かに"string" + 1 だけでは何に変換すべきか分からないですね。
ただWebプログラミングの場合、
フォームから送られてきた値とか
DBから取り出した値とか
型がstrだかnumだか気にするのが面倒で
型を自動変換してくれない言語ではちょくちょくエラーになったりしますね。
まぁ予期しない型に勝手に変換して気付かぬバグが紛れ込むよりは良いのかなやっぱり。
0131デフォルトの名無しさん
2011/02/24(木) 05:12:52.74webなら普通Validator使う罠
0132デフォルトの名無しさん
2011/02/24(木) 09:03:01.87class String
alias :__old_plus__ +
def +(o)
__old_plus__(o.to_s)
end
end
こういう思いつきを簡単に試せるのが、rubyの楽しさ。
0133デフォルトの名無しさん
2011/02/24(木) 09:17:01.960134デフォルトの名無しさん
2011/02/24(木) 09:50:58.010135デフォルトの名無しさん
2011/02/24(木) 12:58:09.08file = File.open('./test.txt','r+')
file.flock(File::LOCK_EX)
sleep(10)
file.close
こんなスクリプトを書いて実行中でも、対象ファイルをcatできたのですが、これはロックに失敗しているんでしょうか?
0136デフォルトの名無しさん
2011/02/24(木) 13:00:11.370137デフォルトの名無しさん
2011/02/24(木) 14:17:12.10ロックには成功してるけど、 >>135 がロックを理解してないと思われ。
cat じゃなくてそのスクリプトを 2 個同時に動かしてみて。
で、ロックについてもっとちゃんと調べれ。
0138デフォルトの名無しさん
2011/02/24(木) 17:03:42.52flockはアドバイザリ・ロック(紳士協定)でしかなく
ファイルのアクセス権とは無関係
ファイルの入出力をも排他制御するのは強制ロックといい、OS依存の処理になる
で、どうでしょうか?
0139デフォルトの名無しさん
2011/02/24(木) 23:02:15.32>>138
なるほど。ぐぐってもrubyで強制ロックを行う方法がでてこないのですが、rubyでは提供されていないのしょうか?
flockもunixのシステムコールだということなので同様にできると考えたのですが…
0140デフォルトの名無しさん
2011/02/24(木) 23:18:12.87出来ると思うが、そもそもOS/ファイルシステムによってmandatory lockは
できたりできなかったり。
0141デフォルトの名無しさん
2011/02/24(木) 23:29:38.28ttp://homepage1.nifty.com/~tetsu/ruby/diary/0102.html
マウントオプションがいるんだな…
0142デフォルトの名無しさん
2011/02/24(木) 23:35:33.82そのUnixシステムコールflockが紳士協定なの。
0143デフォルトの名無しさん
2011/02/25(金) 00:13:54.42(man 2 flock)
0144デフォルトの名無しさん
2011/02/25(金) 02:01:01.22values_atの引数に複数のインデックスを渡しつつ
*を書かずにすむ方法はないでしょうか?
0145デフォルトの名無しさん
2011/02/25(金) 03:39:27.41Array#values_atを書き換えるしかないと思う。
Array.class_eval do
alias _orig_values_at values_at
def values_at(*args)
_orig_values_at(*args.flatten)
end
end
0146デフォルトの名無しさん
2011/02/25(金) 06:45:32.640147デフォルトの名無しさん
2011/02/27(日) 18:40:21.92uri = Addressable::URI.parse("http://hibari.2ch.net/").normalize
p uri.host
これだと「hibari.2ch.net」が返ってきますが「2ch.net」だけ返ってくるメソッドは無いのでしょうか
正規表現で頑張るしかないのでしょうか
■ このスレッドは過去ログ倉庫に格納されています