トップページ⇒tech
983コメント375KB

Ruby 初心者スレッド Part 41

■ このスレッドは過去ログ倉庫に格納されています
0001京 ◆SsSSsSsSSs 2011/02/10(木) 13:47:51
プログラミング言語Rubyについての、初心者向けスレです。質問・要望・雑談などどうぞ。

★注意★ 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 ではブロック引数は被ると考えてもらっていい
被らないバージョンのRubyも存在するが、互換性の問題でこれに頼った記述は全く勧められないので忘れてくれ

a.inject{|x, y| x + y}

とか書くのが一応回答
0049デフォルトの名無しさん2011/02/17(木) 21:15:50
>互換性の問題でこれに頼った記述は全く勧められない
そうなんだよなあ…
何がめんどくさいって、ここが問題で1.8ではうまく動作しないということを見つけるまでが果てしなくめんどくさい
0050デフォルトの名無しさん2011/02/17(木) 22:01:07
>>47
「a」.inject {|「a」, b| 「a」 + b}
上のaは全部同じオブジェクトなのでループしたときにaが上書きされる
0051デフォルトの名無しさん2011/02/17(木) 22:04:25
>>46
&: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
OK, 理解した。ありがとう
&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:26
>Ruby ではブロック引数は被ると考えてもらっていい
1.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
>>53
>互換性の問題でこれに頼った記述は全く勧められないので忘れてくれ
0055デフォルトの名無しさん2011/02/18(金) 00:35:39
ぐぇ〜,みんなありがとう.有名な話だったのね.

っていうか 1.8 が消え去るまで ruby やる気が失せた...

ありえないだろJK.
0056472011/02/18(金) 00:38:00
↑ 47 でした.
0057デフォルトの名無しさん2011/02/18(金) 01:31:00
Rubyではローカルスコープの外に同名の変数があるとそれへの参照となり
なければ新たな変数の定義となる(ただし1.9系のブロック引数は常に後者)

宣言無しで変数を使えますよ系言語の欠点

外側に同名の変数があっても新たな変数を定義できるような構文が欲しくなることがある
0058デフォルトの名無しさん2011/02/18(金) 02:05:13
というか広めのスコープに1文字変数使うやつってなんなの?
ブロック等の一番せまいスコープならまだ許せる
i、jは例外だと思うけど、それでもスコープ狭くするべき
テンポラリでないなら変数にちゃんとした名前つけろ
0059デフォルトの名無しさん2011/02/18(金) 02:09:22
なんなのっていうやつなんなの

以下スタック食いつぶすまで続く
0060デフォルトの名無しさん2011/02/18(金) 02:10:55
もしブロックローカルな変数を他に使いたいときには,ブロック変数に変数宣言をセミコロンで追加すればいい.

x = 1 [2,3].each {|y;x| x = y }

こうすると x は 1 のままになる.
0061デフォルトの名無しさん2011/02/18(金) 02:25:35
もしブロックローカルな変数を他に使いたいときには,ブロック変数に変数宣言をセミコロンで追加すればいい.

x = 1
[2,3].each {|y;x| x = y }

こうすると x は 1 のままになる.
0062デフォルトの名無しさん2011/02/18(金) 02:59:54
もしブロックローカルな変数を他に使いたいときには,ブロック変数に変数宣言をセミコロンで追加すればいい.

x = 1
[2,3].each {|y;x| x = y }

こうすると x は 1 のままになる.
0063デフォルトの名無しさん2011/02/18(金) 03:02:40
もしブロックローカルな変数を他に使いたいときには,ブロック変数に変数宣言をセミコロンで追加すればいい.

x = 1
[2,3].each {|y;x| x = y }

こうすると x は 1 のままになる.
0064デフォルトの名無しさん2011/02/18(金) 03:20:10
もしブロックローカルな変数を他に使いたいときには,ブロック変数に変数宣言をセミコロンで追加すればいい.

x = 1
[2,3].each {|y;x| x = y }

こうすると x は 1 のままになる.
0065デフォルトの名無しさん2011/02/18(金) 08:54:01
1.8のときは、自分でスタックに積んでた。

def 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
>>66
いわゆる挿入モードは一発ではできません、が回答だと思う…
そーゆーもんなので、どうしようもない

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:31
Google Code Jam Japan 2011
http://code.google.com/codejam/japan

rubyでも参加できるらしいぞ。
0069デフォルトの名無しさん2011/02/18(金) 20:58:30
Rubyだと(処理性能的な意味で)力技で通せなさそうだな
0070デフォルトの名無しさん2011/02/19(土) 12:34:33
            end
          }
        end
      }
    end
  end
end
↑はちょっと大げさだけど混在が気持ち悪い。
みな賛同してますか
0071デフォルトの名無しさん2011/02/19(土) 12:35:55
皆さん、どうしてますか?
0072デフォルトの名無しさん2011/02/19(土) 12:52:13
基本{}はワンライナーで書くようにしてる
0073デフォルトの名無しさん2011/02/19(土) 15:20:15
>>70
あまり気にしてない

ちょっと慣れると、エンドという英単語を読んでるわけではない、という境地になる
ただのヨコ長のブロック終端記号だ
0074デフォルトの名無しさん2011/02/19(土) 15:43:09
>>70
>混在が気持ち悪い。
混在は気にしないかな。end自体は気にするけど。
0075デフォルトの名無しさん2011/02/19(土) 17:58:52
ブレースが見た目に浮くことを利用して
リソース管理や大域脱出のブロックはブレースを使って目立たせる
コーディングルールもあったはず
0076デフォルトの名無しさん2011/02/19(土) 23:28:37.73
ご意見ありがとうございました
参考にさせていただきます
0077デフォルトの名無しさん2011/02/20(日) 07:25:41.22
Windows上でファイルをRubyのプログラムに
ドラグ&ドロップしたときの実行パスを取得するには、どうすればいいのでしょうか?
よろしくお願いします。

プログラムを通常実行したなら、File.expand_path(__FILE__)でパスが取れるのですが、
ドラグ&ドロップ時には、File.expand_path(__FILE__)の中身が、
  C:/Documents and Settings/ユーザー名/実行ファイル名.rb
となってしまいます。
0078デフォルトの名無しさん2011/02/20(日) 07:44:55.62
>>77
期待通りだけど何がマズイ?
0079デフォルトの名無しさん2011/02/20(日) 07:46:08.87
>>77
聞き方がおかしかった。どういう値になるのを期待している?

0080772011/02/20(日) 08:03:45.59
>>79
>聞き方がおかしかった。どういう値になるのを期待している?
c:\temp\program.exe
の上にファイルをドラッグしたら、c:\tempのパスが取得できることを期待しています。
(プログラム自体は、program.rbをexerbでprogram.exeに変換しています)

できれば「program.exeへのショートカット」上にドラッグしたとしても、
元のc:\temp\program.exeの実行パスを取得したいです。
0081デフォルトの名無しさん2011/02/20(日) 10:08:07.34
>>80
ttp://exerb.sourceforge.jp/man/doc/class.ja.html
0082772011/02/20(日) 14:52:00.80
>>81
ありがとうございます。とても助かりました。
0083デフォルトの名無しさん2011/02/20(日) 23:24:10.74
>>70
Python に乗り換えた
0084デフォルトの名無しさん2011/02/21(月) 08:00:25.78
Windows上で ruby 1.9.2 を使い、ファイル名がUNICODEで
ファイルの中身がWindows-31Jのテキストファイルで正規表現を使うにはどうしたら良いの?
# coding:utf-8 と書くとファイルは開けるけど正規表現でエラー
# coding:Windows-31Jと書くとファイル名が文字化けして開けず
0085デフォルトの名無しさん2011/02/21(月) 08:09:36.27
文字エンコーディングの概念ない奴は1.8使えバーカバーカって煽られそうな内容だな
マジックコメントにはソースファイルの文字エンコーディングを記述する
openに渡すファイルパス名のStringオブジェクトの文字エンコーディングをUTF-8にして
マッチに使う正規表現の文字エンコーディングをWindows-31Jにすればよかんべ
Ruby1.9はぜんぶ別個にできるぞ
0086デフォルトの名無しさん2011/02/21(月) 08:50:12.61
あと、読み込むファイルのエンコーディングも
ばらばらに指定できるぞ。
0087デフォルトの名無しさん2011/02/21(月) 10:32:40.65
>>84
>ファイルの中身がWindows-31Jのテキストファイルで正規表現を使うにはどうしたら良いの?
こっちを優先して、コードはwindows-31jで書く。
ほんで、ファイル名を表す文字列はunicodeに変換してやる。
0088デフォルトの名無しさん2011/02/21(月) 10:49:29.19
おまい頭いいな
0089デフォルトの名無しさん2011/02/21(月) 14:13:01.98
Ruby初心者向け1.9文字エンコーディング教室とかサイト作ったら繁盛するかな
0090デフォルトの名無しさん2011/02/21(月) 15:09:28.21
絶対繁盛するからやってくれよ
0091デフォルトの名無しさん2011/02/21(月) 18:01:35.10
つーかファイル名をutf-8で直書きすれば普通に開けるのを今知った。M系APIだとばかり
ARGVはダメっぽい?
0092842011/02/21(月) 20:18:15.66
自己解決しました。自分も>>87の方法に行き着きました。

あと、Encoding.default_internal がよく分かりません。
指定しておくと読み込んだ内容がその文字コードに変換されるのかと思ったんですが……
0093デフォルトの名無しさん2011/02/22(火) 00:51:00.99
>>80
ちょっと遅レスだが
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.41
rvm使ってる人は自分用CGI起動するRubyとかgemとかどうしてるの?
0095デフォルトの名無しさん2011/02/22(火) 15:59:04.40
>>89
むしろ、昔から使ってるひと向けに
0096デフォルトの名無しさん2011/02/22(火) 16:05:11.22
中学生が書いたパッチ見たけどさっぱりわからなかった。
0097デフォルトの名無しさん2011/02/22(火) 16:30:55.98
むしろ中学生が書くとプログラムという半定型文法文の何が変わるつもりだったのか>>96に聞いてみたい
0098デフォルトの名無しさん2011/02/22(火) 16:40:10.29
たわいもないレスにむきになりすぎだとおもいます。
0099デフォルトの名無しさん2011/02/22(火) 17:26:16.31
これか

リアル中2、Ruby最年少コミッタに就任【増田(@maskin)真樹】
http://techwave.jp/archives/51599766.html
0100デフォルトの名無しさん2011/02/22(火) 17:34:49.25
これはいいニュースだ。将来は第2代教皇だな
0101デフォルトの名無しさん2011/02/22(火) 19:34:27.07
スレッドについて初心者が学ぶのに最適な書籍はあるでしょうか
手元にあるたのしいRubyには全く載っていませんでした
0102デフォルトの名無しさん2011/02/22(火) 20:00:56.10
そもそものスレッドに関しての知識があれば楽勝

とかいうようなシロモノなので結構厳しい
0103デフォルトの名無しさん2011/02/22(火) 21:58:19.20
ダグリーの本のRuby版みたいなのか
あったらいいね
0104デフォルトの名無しさん2011/02/22(火) 22:05:43.44
だれやねん、それ
0105デフォルトの名無しさん2011/02/22(火) 22:12:17.94
調べずに書くが、並列処理とかで有名な大学教授
JavaのConcurrentパッケージとか日本語訳もされてる
並列処理関連のJava本を書いてたような
0106デフォルトの名無しさん2011/02/23(水) 00:34:22.12
『Java並行処理プログラミング 』はいい書籍だが、
Doug Leaはダグリーって呼ぶのだろうか……?
0107デフォルトの名無しさん2011/02/23(水) 00:48:35.76
ダグ=リーかダッグ=リーだと思う
0108デフォルトの名無しさん2011/02/23(水) 01:54:16.68
>>106
普通に英語読みしたらダグリーだけど
実は英語圏出身じゃなくて読み方が微妙に違うとか何とかあるのかい?
0109デフォルトの名無しさん2011/02/23(水) 02:04:44.44
フルネームは Douglas Lea なわけで、
DougはDouglas の愛称のダグなので確定として、
Leaのほうは、英語読みすればリーかな、程度だなぁ。

ま、実際彼の名のカタカナ書きはダグ・リーが一般的。
0110デフォルトの名無しさん2011/02/23(水) 06:44:52.71
RubyとかCとかJavaとかLispとか色々使える人が、
「ここはRubyで書くかな」って判断する基準って何かありますか?
0111デフォルトの名無しさん2011/02/23(水) 06:54:51.44
>>110
そんなものはない
Rubyで書きにくい・動かしにくい・指定されてないから他の言語で書く
0112デフォルトの名無しさん2011/02/23(水) 07:53:36.19
Rubyのほうが低コストなとき
0113デフォルトの名無しさん2011/02/23(水) 09:02:46.90
Lisp以外との比較なら、メタプログラミングならRuby。
マクロならLisp。
0114デフォルトの名無しさん2011/02/23(水) 10:07:20.76
文字列処理が多いならRuby
再帰が多いならScheme
GUI扱うならJava
ライブラリ開発や、OSのAPIとか使いまくるならC
0115デフォルトの名無しさん2011/02/23(水) 16:06:26.92
class Vec
attr_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.56
var = 1

puts "this number is #{var}" => this number is 1
puts "this number is" + var => エラー

この仕様は何か意図があるんでしょうか。。
fixnumを自動でstringに変換してくれてもいいのに、って思ってしまいます。
譲って後者をエラーにするのであれば前者もエラーにすべきとも思います。
rubyistの方のどのように考えているのですか?
0117デフォルトの名無しさん2011/02/23(水) 17:09:35.97
>>115
ぶっちゃけ最初はよくわからないと思う
クラス定義の中から使うなら @変数 を使う、
クラス定義の外から使うならメソッド使う、でしばらくいっと毛
0118デフォルトの名無しさん2011/02/23(水) 17:30:30.29
>>116
var = 1
puts "this number is #{var}" # varがto_sされるのは誰が見ても明らか
puts "this number is " + var # これも明らか
other_var + var # どうだっけ
0119デフォルトの名無しさん2011/02/23(水) 17:32:18.51
>>118は + で一方のオペランドの自動変換を許した場合のシナリオ
0120デフォルトの名無しさん2011/02/23(水) 17:37:21.52
>>116
思いっきり大前提として、「+は表示用連結記号ではない」というのをしっかり認識して欲しいと思う
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.67
String#+ が to_s を呼ばないのはなんで、という話はもう太古の昔からあるな

 Stringオブジェクト + foo
は
 "ABC#{foo}DEF"
ほど foo を文字列化する意図が明確ではないのでとりあえず例外出して止める、
+ で連結したいなら foo をなんとかして自力で文字列化しろ、というのがいちおう回答ではあるのだが
0122デフォルトの名無しさん2011/02/23(水) 17:47:51.62
str + num は、交換法則とか考えると面倒なので、例外がシンプルで良いと思う。
0123デフォルトの名無しさん2011/02/23(水) 18:14:52.42
% irb
irb(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
puts "1" + 2
=> 12
こうなってほしいの? 俺は嫌だ。むしろ3になって欲しい
0125デフォルトの名無しさん2011/02/23(水) 19:02:59.66
>>> print "1" + 2
Traceback (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
>>116
すでに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
>>120
説明が長いよ・・・初心者がそんなの読むわけないじゃん
0128デフォルトの名無しさん2011/02/23(水) 23:39:41.73
>>115
アクセサを作らずにやったら違いが解ると思う
0129デフォルトの名無しさん2011/02/24(木) 00:30:00.56
>>115
direct variable access と indirect variable access でぐぐって。
どっちを使うかはケースバイケース。
01301162011/02/24(木) 02:47:08.45
回答してくれた方、丁寧にありがとうございました。よく分かりました。

#{うめこみ} と puts "string" + 1
を比較するのではなく、
#{うめこみ} と "string" + 1
を比較しないと駄目、というところで氷解しました。
確かに"string" + 1 だけでは何に変換すべきか分からないですね。

ただWebプログラミングの場合、
フォームから送られてきた値とか
DBから取り出した値とか
型がstrだかnumだか気にするのが面倒で
型を自動変換してくれない言語ではちょくちょくエラーになったりしますね。
まぁ予期しない型に勝手に変換して気付かぬバグが紛れ込むよりは良いのかなやっぱり。
0131デフォルトの名無しさん2011/02/24(木) 05:12:52.74
>>130
webなら普通Validator使う罠
0132デフォルトの名無しさん2011/02/24(木) 09:03:01.87
Ruby は、オープンクラスだから、便利だと思ったら自己責任で勝手に改造すればいい。
class String
 alias :__old_plus__ +
 def +(o)
   __old_plus__(o.to_s)
 end
end
こういう思いつきを簡単に試せるのが、rubyの楽しさ。
0133デフォルトの名無しさん2011/02/24(木) 09:17:01.96
>>132は初心者
0134デフォルトの名無しさん2011/02/24(木) 09:50:58.01
標準クラスの既存のメソッドを改変するのはよろしくないな
0135デフォルトの名無しさん2011/02/24(木) 12:58:09.08
#!/usr/bin/ruby

file = File.open('./test.txt','r+')
file.flock(File::LOCK_EX)
sleep(10)
file.close

こんなスクリプトを書いて実行中でも、対象ファイルをcatできたのですが、これはロックに失敗しているんでしょうか?
0136デフォルトの名無しさん2011/02/24(木) 13:00:11.37
もちろんです
0137デフォルトの名無しさん2011/02/24(木) 14:17:12.10
>>135
ロックには成功してるけど、 >>135 がロックを理解してないと思われ。
cat じゃなくてそのスクリプトを 2 個同時に動かしてみて。
で、ロックについてもっとちゃんと調べれ。
0138デフォルトの名無しさん2011/02/24(木) 17:03:42.52
他人ですが調べてみた

flockはアドバイザリ・ロック(紳士協定)でしかなく
ファイルのアクセス権とは無関係
ファイルの入出力をも排他制御するのは強制ロックといい、OS依存の処理になる

で、どうでしょうか?
0139デフォルトの名無しさん2011/02/24(木) 23:02:15.32
>>135
>>138

なるほど。ぐぐってもrubyで強制ロックを行う方法がでてこないのですが、rubyでは提供されていないのしょうか?
flockもunixのシステムコールだということなので同様にできると考えたのですが…
0140デフォルトの名無しさん2011/02/24(木) 23:18:12.87
fcntlやioctlを使えば、対象OSのシステムコールで出来るのと同等のことは
出来ると思うが、そもそもOS/ファイルシステムによってmandatory lockは
できたりできなかったり。
0141デフォルトの名無しさん2011/02/24(木) 23:29:38.28
Linuxの場合。ほぼ10年前の文章
ttp://homepage1.nifty.com/~tetsu/ruby/diary/0102.html

マウントオプションがいるんだな…
0142デフォルトの名無しさん2011/02/24(木) 23:35:33.82
>>139
そのUnixシステムコールflockが紳士協定なの。
0143デフォルトの名無しさん2011/02/25(金) 00:13:54.42
まぁ、できないということを納得するにはまずは flock(2) を読むことだな。
(man 2 flock)
0144デフォルトの名無しさん2011/02/25(金) 02:01:01.22
arr.values_at(*foo())ではなくarr.values_at(foo())と書けるようにしたい
values_atの引数に複数のインデックスを渡しつつ
*を書かずにすむ方法はないでしょうか?
0145デフォルトの名無しさん2011/02/25(金) 03:39:27.41
>>144
Array#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.64
やっぱりそうですか。ありがとうございました。
0147デフォルトの名無しさん2011/02/27(日) 18:40:21.92
URLのサブドメインを除去したドメインのみを取得したいです

uri = Addressable::URI.parse("http://hibari.2ch.net/").normalize
p uri.host

これだと「hibari.2ch.net」が返ってきますが「2ch.net」だけ返ってくるメソッドは無いのでしょうか
正規表現で頑張るしかないのでしょうか
■ このスレッドは過去ログ倉庫に格納されています