Ruby 初心者スレッド Part 25
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
2009/01/31(土) 11:31:07【Ruby1.9.1 は従来版とは別物であり、書籍や解説やライブラリのサポートがまだありません】
【自力で解決できない壁で悩むことのない最新安定版の Ruby1.8.7 での学習をお勧めします】
※1.8.7 は 1.8 系と 1.9 系の橋渡しをするためのリリースで、1.9 系 の便利新機能の一部が利用可能です
※ただし 1.8.6 より安定しているとはまだ言えないので、安定性を第一とする用途には 1.8.6 をどうぞ
関連スレや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を読め」でいいので、叩かない&怖がらせない。
・わけわかな質問にもエスパー発揮で。できれば質問の仕方を教えるぐらいで。
・自信がない回答ならその旨表明すること。誤った回答は初心者じゃ見抜けない。
0153デフォルトの名無しさん
2009/02/01(日) 14:44:371.9 版は誰かが作ってくれだってさ
0154デフォルトの名無しさん
2009/02/01(日) 14:50:08そこまで別言語じゃないよ。
どっちでも動く記述方法はだいたい提供されてる。
>>153
なんてライブラリ?
0155デフォルトの名無しさん
2009/02/01(日) 15:05:44配列の参照のコピーじゃなくて、値そのものを別の変数に代入して
元の配列の中身を壊さないように、コピー先の変数の中身を変更したいのです。
0156デフォルトの名無しさん
2009/02/01(日) 15:09:02コードでおk
0157デフォルトの名無しさん
2009/02/01(日) 15:09:38単なる数値の配列なら dup で事足りる。
もっと深いコピーが必要なら、少し工夫が必要になる。
0158デフォルトの名無しさん
2009/02/01(日) 15:14:170159デフォルトの名無しさん
2009/02/01(日) 15:15:22ただし、Marshalできないオブジェクトが含まれていると使えない
0160デフォルトの名無しさん
2009/02/01(日) 15:15:34b = a
b[0] = "X"
p a, b
#=> ["X", "B", "C"], ["X", "B", "C"]
これを
#=> ["A", "B", "C"], ["X", "B", "C"]
にしたいってこと?
>>157の言うように b = a.dup でよろし
>>158
配列の全体コピーはRuby書き始めの頃は毎回やってたが、最近はほとんどしないな
0161デフォルトの名無しさん
2009/02/01(日) 15:18:18to_a を作るか to_ary を作るかで迷ってるのでアドバイスください糞どもお願いします
0162デフォルトの名無しさん
2009/02/01(日) 15:19:550163デフォルトの名無しさん
2009/02/01(日) 15:23:08to_a
Object#to_a は obsolete だが、あれは全クラスに影響する Object クラスだからなので気にしなくていい
配列にしたいという陽な意図なら to_a を作るべきだと思う
0164デフォルトの名無しさん
2009/02/01(日) 15:29:550165155
2009/02/01(日) 15:31:42解決できたんですが、がんばってサンプルコード書いてたので、
やりたかったのは下のようなことでした。
ORIG =
{
:test1 => "1:%1%",
:test2 => "10:%1%",
}
a = ORIG[:test1]
puts "original=" + ORIG[:test1] + "\n"
puts "change=" + a + "\n"
a.gsub!("%1%", "change")
puts "original=" + ORIG[:test1] + "\n"
puts "change=" + a + "\n"
で、
a = ORIG[:test1].dup
で希望通りになりました。
ありがとうございました。
0166デフォルトの名無しさん
2009/02/01(日) 15:42:32a2 = a.gsub("%1%", "change")
というように別変数が作れるように書くと思う
dup でオリジナル丸ごとコピーはしないかも
0167デフォルトの名無しさん
2009/02/01(日) 16:05:52のちのちフックする処理が発生しそうな気がするのでアクセサを経由しようと思います
class Hoge
attr_accessor :val1, val2, val3
def main(params)
val1 = params[0]
val2 = params[1]
...
こんな感じです
が、なんかローカル変数っぽくてちょっと残念です
1. val1 = params[0] でいいじゃん
2. val1() = params[0] でどうだ
3. self.val1 = params[0] が妥当
4. val1 = params[0] # @val1
どんなもんでしょう
0168デフォルトの名無しさん
2009/02/01(日) 16:11:47次点で4
val1のように名前がローカルっぽい雰囲気で紛らわしい場合は3
2は「引数のないメソッド呼び出しは ( ) を省略する傾向にある」というRubyの書き方のほうに踏み込んでて超キモい
0169デフォルトの名無しさん
2009/02/01(日) 16:12:53例えばクラス生成時に initialize でデータベースに接続し、デストラクタで切断
みたいにやりたのだけども。
自前で接続、切断のメソッドを作成して明示的に呼ぶのが ruby っぽいやり方でしょうか?
0170デフォルトの名無しさん
2009/02/01(日) 16:18:36ローカル変数っぽいっていうか、実際ローカル変数の代入になってると思うぞ。
その選択肢なら3以外は動いてない。
0171デフォルトの名無しさん
2009/02/01(日) 16:19:34ブロック終了時に切断とかの終了処理すればいい
0172デフォルトの名無しさん
2009/02/01(日) 16:21:00class DB
def self.transaction
db = DB.new
yield db
db.close
end
def close
# 終了処理
end
end
みたいなメソッドを用意する。
DB.transaction do |db|
# db をいじる
end
0173デフォルトの名無しさん
2009/02/01(日) 16:26:41文脈依存でやや紛らわしい
やや
0175デフォルトの名無しさん
2009/02/01(日) 16:50:54常に val というローカル変数への代入とみなされて、アクセサ経由で代入をすることはできない?
っていうかそうなってるな
irb> def val=(a); p "Woo!"; end
irb> val=(1)
1
irb> self.val=(1)
"Woo!"
1
0176デフォルトの名無しさん
2009/02/01(日) 17:01:24yield内のユーザーコードで何か起こっても終了処理が行われるように
db = DB.new
begin
yield db
ensure
db.close
end
のようにensureを使うのを推奨。
0177デフォルトの名無しさん
2009/02/01(日) 17:02:43メソッド呼ぶときは常に self つけておいたほうがいいのかなあ
0178デフォルトの名無しさん
2009/02/01(日) 17:04:27privateメソッドが呼べなくなるぞ
0179デフォルトの名無しさん
2009/02/01(日) 17:39:202はキモいどころかsyntax error
0180デフォルトの名無しさん
2009/02/02(月) 02:55:270181デフォルトの名無しさん
2009/02/02(月) 03:04:18考えまでは当たってるけど、若干間違ってるので突っ込んでおく。
1.2、1.4、1.6、1.8、2.0等の偶数番号のリリースが安定公開版。
1.3、1.5、1.7、1.9等の奇数番号のリリースは開発版。
0182デフォルトの名無しさん
2009/02/02(月) 03:39:10全角20文字分の文字を先頭から取り出す処理したいのですが、
文字数で指定すると取り出した文字に半角が多かった場合、全角20文字のスペースが余りますよね。
どのようにして全角20文字分の文字を全角・半角が混在した文字列から取り出したらいいのでしょうか。
0183デフォルトの名無しさん
2009/02/02(月) 03:40:38知ってたような知らんかったような、とりあえずthx☆
0184デフォルトの名無しさん
2009/02/02(月) 04:08:371.9からその方針は変わった。1.9.1は純然たる安定版。
0185デフォルトの名無しさん
2009/02/02(月) 05:45:07>>182
「全角半角関係なく20文字取り出したい」だと判断
str.split(//E)[0..20]
E は str の文字エンコード、ShiftJISならs、EUC-JPならe、UTF-8ならu
irb> str = "外部ライブラリ不備のRuby1.9.1はうんこ"
irb> puts str[0..19]
外部ライブラ懽
irb> puts str.split(//u)[0..19].to_s
外部ライブラリ不備のRuby1.9.1は
0186デフォルトの名無しさん
2009/02/02(月) 05:47:38なんとしても2.0を出したくないからってポリシー変えたんだよな
安易にメジャーバージョン上げないという点では好ましいが、
そこまでするかという気もする
0187デフォルトの名無しさん
2009/02/02(月) 07:02:26なんとしても2.0を出したくないって変なところで強気だよなwww
0188デフォルトの名無しさん
2009/02/02(月) 07:49:02そうすれば「ああ2.0.xでは仕様が大きく変わってるんだなぁ」と、初心者にもある程度分かったはず
そうして次期Ruby(Rite?)を3.0.xにしてくれれば丸く収まっていた
0189デフォルトの名無しさん
2009/02/02(月) 07:51:580190デフォルトの名無しさん
2009/02/02(月) 10:01:120191デフォルトの名無しさん
2009/02/02(月) 11:23:08だから1.9系は違うと・・・初めてのRuby(P10)で開発者メンバーが書いてるんだから間違いない
1.9.0→開発版、1.9.X(X > 0)安定版
0192デフォルトの名無しさん
2009/02/02(月) 11:42:03さりとて、1.10にもしたくない。
仕方なく、奇数でも安定バージョンにしたと。
0193デフォルトの名無しさん
2009/02/02(月) 11:50:45最新数レスしか世界が無いみたいで可哀想
0194デフォルトの名無しさん
2009/02/02(月) 12:47:21str[/.{20}/e]がおすすめ。
ちなみに1.9ならstr[0, 20]だけでいい。
0195デフォルトの名無しさん
2009/02/02(月) 13:17:47亀だが3
ローカル変数への代入との区別の兼ね合いで、3みたいな形は
val1=()がprivateでも呼べる。
0196デフォルトの名無しさん
2009/02/02(月) 13:33:48C
irb> C.new.m1
NoMethodError: private method `xxx' called for #<C:0xb7c12304>
irb> C.new.m2
NoMethodError: private method `xxx' called for #<C:0xb7c10388>
irb> class C; def m1; C.new.xxx=0; end; def m2; self.xxx=0; end; def xxx=(s); end; private :xxx=; end
C
irb> C.new.m1
NoMethodError: private method `xxx=' called for #<C:0xb7bf0100>
irb> C.new.m2
0
変な挙動…
0197デフォルトの名無しさん
2009/02/02(月) 13:43:21trapにも書いてあるな
ttp://www.ruby-lang.org/ja/man/html/trap_A5B9A5B3A1BCA5D7A1A2C0A9B8E6B9BDC2A4.html
> ローカル変数と等号付きメソッド
> レシーバを省略するとメソッドではなくローカル変数として扱われます。
> 普通のメソッドはselfのレシーバを省略できますが、この場合は不可。
class Foo
def bar=(v)
end
def baz
bar = 0 # ローカル変数 bar への代入
self.bar = 0 # メソッド bar= の呼び出し
end
end
0198デフォルトの名無しさん
2009/02/02(月) 14:01:47その過去レスを見ないやつのためにソースも出してレスし直したわけだが
0199デフォルトの名無しさん
2009/02/02(月) 16:49:02つ おまいの出したのはソースじゃなく本な件について
0200デフォルトの名無しさん
2009/02/02(月) 17:07:190201デフォルトの名無しさん
2009/02/02(月) 17:08:140202デフォルトの名無しさん
2009/02/02(月) 17:12:45ひどすぎるいいがかりだなw
>>198
ずいぶん前に、バージョンの名づけポリシーが変わった記憶はある。
でも、↓見ると元に戻ったのかとか、何かの勘違いだったんだろうかとか思ってしまう。
http://www.atmarkit.co.jp/news/200712/25/ruby.html
まあ、これより新しいソースがあると知って安心したよ。
0203デフォルトの名無しさん
2009/02/02(月) 17:47:04マージとかindexとかもうわけわかめ
0204デフォルトの名無しさん
2009/02/02(月) 17:52:55hash1.merge(hash2) {|key, self_val, other_val| self_val + other_val }
0205デフォルトの名無しさん
2009/02/02(月) 17:53:560206デフォルトの名無しさん
2009/02/02(月) 18:00:07やりたいことを頭に描いてひとつひとつ実装してくといい
ベンリ機能でカッコよく書き換えようとするのはそのあとだ
頭の中ではっきりしてないから、わけがわからなくなる
hash_a = {"a" => "1", "b" => "2"}
hash_b = {"a" => "1", "c" => "3"}
hash_a.each_pair do |key_a, val_a|
if hash_b.has_key?(key_a)
hash_a[key_a] = val_a + hash_b[key_a]
end
end
0207デフォルトの名無しさん
2009/02/02(月) 18:01:30ハッシュは一つでその中でキーが同じときなんだけど 大丈夫かしら?
0208デフォルトの名無しさん
2009/02/02(月) 18:08:24そういうことか、ハッシュに代入するときとか言ってくれw
+が破壊的じゃないという前提で
h = Hash.new(0)
h[:key] += 1
h[:key] += 2
puts h[:key] # -> 3
文字列だったらHash.new("")とか。
ただこの初期値は共通のオブジェクトを使い回すというクセがあるから
取り扱いに注意。
0209デフォルトの名無しさん
2009/02/02(月) 18:10:240210デフォルトの名無しさん
2009/02/02(月) 18:10:37if hash.key? key
hash[key] += value
else
hash[key] = value
end
こっちのほうがHash.newの罠もないし確実。
0211デフォルトの名無しさん
2009/02/02(月) 18:15:28k, v = "a", "3"
if h.has_key?(k)
h[k] = h[k] + v
end
これでいいじゃんね
…自動でやりたい?
class MyData < Hash
def []=(k, v)
if self.has_key?(k) then
store(k, self[k] + v)
else
store(k, v)
end
end
end
data = MyData[{"a" => "1", "b" => "2"}]
data["a"] = "3"
p data
#=> {"a"=>"13", "b"=>"2"}
0212デフォルトの名無しさん
2009/02/02(月) 22:46:570213デフォルトの名無しさん
2009/02/02(月) 22:54:15欲しいのはwordがkey1で何回,key2で何回・・・って
最初に呼び出すときにhash1.each{|key,value|・・・てやるとその括弧ないではhash1は呼び出せないよね?
0214デフォルトの名無しさん
2009/02/02(月) 23:03:33word = ["a", "b", "c"]
h1 = {"1"=>"a", "2"=>"b", "3"=>"b", "4"=>"c", "5"=>"c", "6"=>"c"}
counts = Hash.new
word.each do |e|
counts[e] = 0
end
h1.each_pair do |key,val|
if counts.has_key?(val) then
counts[val] = counts[val] + 1
end
end
p counts
結果
{"a"=>1, "b"=>2, "c"=>3}
0215デフォルトの名無しさん
2009/02/02(月) 23:22:12word = ["a", "b", "c"]
h1 = {"A"=>"abcabc", "B"=>"abbbc", "C"=>"aaccc"}
だと
結果が
{
"a"=>{"A"=>2,"B"=>1,"C"=>2},
"b"=>{"A"=>2,"B"=>3,"C"=>0},
"c"=>{"A"=>2,"B"=>1,"C"=>3},
} になってほしいのですけど・・・・・
0216デフォルトの名無しさん
2009/02/02(月) 23:33:44words = ["a", "b", "c"]
h1 = {"A"=>"abcabc", "B"=>"abbbc", "C"=>"aaccc"}
results = Hash.new
words.each{|e| results[e] = Hash.new}
h1.each_pair do |key, val|
results.each_pair do |word, counts|
counts[key] = val.scan(/#{word}/).flatten.size
end
end
require 'pp'
pp results
結果:
{"a"=>{"A"=>2, "B"=>1, "C"=>2},
"b"=>{"A"=>2, "B"=>3, "C"=>0},
"c"=>{"A"=>2, "B"=>1, "C"=>3}}
っしゃ
0217デフォルトの名無しさん
2009/02/03(火) 00:15:50は
val.count(word)
でよくね?
0218デフォルトの名無しさん
2009/02/03(火) 00:30:27count で用が済むのならそっちのほうが字面もいいかも
0219デフォルトの名無しさん
2009/02/03(火) 00:41:25kwsk
0220デフォルトの名無しさん
2009/02/03(火) 11:09:38もうちょっとだけ続くんじゃ
0221デフォルトの名無しさん
2009/02/03(火) 12:39:072005年4月1日に、1.8.0x1FFFFFまでやることが決まってるよ?
0222デフォルトの名無しさん
2009/02/03(火) 17:10:070223デフォルトの名無しさん
2009/02/03(火) 17:16:33初心者にはそれほど役立たないまたは初心者が読めないので1.9変更点を記述したものなら既にあるが
0224デフォルトの名無しさん
2009/02/03(火) 17:23:25オライリーの最新Ruby本の2冊は1.9系対応だよ
0225デフォルトの名無しさん
2009/02/03(火) 17:27:39>>224
ありがとうございます☆
0226デフォルトの名無しさん
2009/02/04(水) 03:59:17標準ライブラリだけじゃ意味無いだろ。
0227デフォルトの名無しさん
2009/02/04(水) 04:50:12周りの対応次第なのでなんとも言えない状況
0228デフォルトの名無しさん
2009/02/04(水) 05:15:24周りの対応状況で1.9を地雷というのは可笑しい
標準ライブラリ以外は基本的に第三者提供のもの
対応するもしないも作成した第三者が決めるものであって
Rubyのリリースする人達は関係無い話
それでも文句あるなら1.9を使用しなきゃ良いだけ
0229デフォルトの名無しさん
2009/02/04(水) 05:21:510230デフォルトの名無しさん
2009/02/04(水) 06:08:220231デフォルトの名無しさん
2009/02/04(水) 06:35:390232デフォルトの名無しさん
2009/02/04(水) 07:03:23そんなこと言い出したら、C言語で十分とか、きりがない
0233デフォルトの名無しさん
2009/02/04(水) 07:24:13> そんなこと言い出したら、C言語で十分とか、きりがない
言い出したが最後、キリなく突き詰める奴が馬鹿なだけだろう。
0234デフォルトの名無しさん
2009/02/04(水) 09:18:540235デフォルトの名無しさん
2009/02/04(水) 16:14:490236デフォルトの名無しさん
2009/02/04(水) 16:41:14[1.0],
[1.0]]
っていう配列があって、内側の[[0][0]+[1][0]+[2][0],[0][1]+0+0]という
配列が欲しいっすけど、普通に足したらnilってなるんですけどnilってなんですか?
やっぱ、0で初期化しないといけないんっすかね?
0237デフォルトの名無しさん
2009/02/04(水) 16:44:34エスパー募集ですか。。。
分かるところだけ答えると、nilは「値がない」とかそんなような意味。
0238デフォルトの名無しさん
2009/02/04(水) 16:46:50他の言語やってたら「null」ってあるだろ、「nil」はそんなもん
0で初期化って概念も無い
0239デフォルトの名無しさん
2009/02/04(水) 16:47:550240デフォルトの名無しさん
2009/02/04(水) 16:48:310241デフォルトの名無しさん
2009/02/04(水) 16:50:220+1 #=> 1
0+0 #=> 0
0242デフォルトの名無しさん
2009/02/04(水) 16:55:27a = [[0.5, 0.5], [1.0], [1.0]]
res0 = a[0][0] + a[1][0] + a[2][0]
res1 = a[0][1] + 0 + 0
ということで、
>>236
Rubyには多重配列というものはない
多重配列のように見えるものはそのひとつ前のオブジェクトにメソッドを作用させたものに過ぎない
a[1][0]は「配列a の [0, 1] 番地の要素」ではなく「a[0] の返り値に対しての [1]」
よって、[1.0][1] は配列要素が 1個なのに2要素目を参照してるから、nil だ
0243デフォルトの名無しさん
2009/02/04(水) 17:00:48>>242
> a[1][0]は「配列a の [0, 1] 番地の要素」ではなく「a[0] の返り値に対しての [1]」
a[1][0]は「配列a の [1, 0] 番地の要素」ではなく「a[1] の返り値に対しての [0]」
a = [[0.5, 0.5], [1.0], [1.0]]
を、事前に
a = [[0.5, 0.5], [1.0, 0.0], [1.0, 0.0]]
に相当する配列に事前に自動で書き換えるか生成時に固定サイズで0.0で埋めておくか、
あるいは加算処理時に「nilなら0.0とみなす」という処理を書くのが妥当かと
0244デフォルトの名無しさん
2009/02/04(水) 17:09:28配列作ったときに 0.0 で埋めてもらうべきだね
最初のデータ生成処理部分が手ぇ抜いてるんだな
0245デフォルトの名無しさん
2009/02/04(水) 17:44:39でaをeachで>>236みたいに足すときってどうすればいい?
0246デフォルトの名無しさん
2009/02/04(水) 17:47:47落ち着いて配列要素ごとにひとつずつ書け
最初から「カッコいい」短い書き方である必要性は何もない
0247デフォルトの名無しさん
2009/02/04(水) 17:49:06数が多いし数十のファイルで走らせるから汎用性が欲しいんだお
0248デフォルトの名無しさん
2009/02/04(水) 17:54:49だから汎用的に書けばいいだろ
汎用的に使える処理を組み出すんだよ
0249デフォルトの名無しさん
2009/02/04(水) 17:59:56VBAで作られているわけではない。
C++で作られているのだ。
0250デフォルトの名無しさん
2009/02/04(水) 18:07:22test2 = [[0.5, 0.5], [1.0, 1.0], [1.0, 1.0, 1.0], [0.5]]
def addup(arr)
result = Array.new
maxsize = arr.map{|a| a.size}.max
0.upto(maxsize-1) do |i|
subtotal = 0.0
arr.each do |a|
if a[i] == nil then
subtotal = subtotal + 0.0
else
subtotal = subtotal + a[i]
end
end
result << subtotal
end
return result
end
p addup(test1)
p addup(test2)
0251デフォルトの名無しさん
2009/02/04(水) 18:24:26a = [[0.5, 0.5], [1.0], [1.0]]
sum = [0, 0]
a.each_index do |i|
a[i].each_index do |j|
s = a[i][j] || 0
sum[j] += s
end
end
p sum
0252デフォルトの名無しさん
2009/02/04(水) 18:46:05Ruby人口が増えて某言語みたいになったらなんかさびしいな
■ このスレッドは過去ログ倉庫に格納されています