Ruby 初心者スレッド Part 33
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
2009/12/05(土) 14:21:25★注意★ 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を読め」でいいので、叩かない&怖がらせない。
・わけわかな質問にもエスパー発揮で。できれば質問の仕方を教えるぐらいで。
・自信がない回答ならその旨表明すること。誤った回答は初心者じゃ見抜けない。
0153デフォルトの名無しさん
2009/12/13(日) 00:38:42そうですね。本当はそれが知りたかったわけですが・・・。
グローバル変数にすればいいんだけど、なんか気持ち悪い。
0154デフォルトの名無しさん
2009/12/13(日) 00:41:31みたいなのはないんでしょうか?
・・・たぶんないんでしょうね
0155デフォルトの名無しさん
2009/12/13(日) 00:44:42渡すくらいかね。
0156デフォルトの名無しさん
2009/12/13(日) 00:48:32オブジェクト自体を書き換えることはできるよね?
def method(str) {str.gsub! /a/, '!'}
x = "katakana"
puts x #=> "katakana"
method x
puts x #=> "k!t!k!n!"
0157デフォルトの名無しさん
2009/12/13(日) 00:48:47議論によって問題の所在がはっきりしてきました。
おつきあいありがとうございます。
0158デフォルトの名無しさん
2009/12/13(日) 00:51:40それはたぶん文字の配列わたしてるですね。
0159デフォルトの名無しさん
2009/12/13(日) 00:53:100160デフォルトの名無しさん
2009/12/13(日) 00:53:230161156
2009/12/13(日) 00:54:39Ruby のStringオブジェクトの内部ってArrayで表現されていたんですか?
知りませんでした。><
C言語みたいですね。
0162デフォルトの名無しさん
2009/12/13(日) 00:56:25普通の言語なら文字列の扱いはそうなってるんじゃないかなぁ?
0163デフォルトの名無しさん
2009/12/13(日) 01:06:12X='12'
def f
X.gsub!('12','2')
end
f()
p eval(X)
0164デフォルトの名無しさん
2009/12/13(日) 01:22:35文字列がイミュータブル(変更不可)な言語は普通にあるよ
Pythonなんかもそう
>>> s = 'abc'
>>> s[0] = 'A'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
上のごちゃっとしたところをまとめると
* 変数はオブジェクトに付けられた矢印(あるいはラベル)。例: a = [1,2,3]
* 変数を通じてオブジェクトを操作することが出来る。例: a[0], a[1]
* Rubyの文字列はミュータブル(変更可能)なので
変数が指すオブジェクトの中身を書き換えることができる。例: a[1] = 20 # [1,20,3]
0165156
2009/12/13(日) 01:24:26自分なりに調べてみました。
def method(obj)
obj.object_id
end
str = "katakana"
p str.object_id #=> 69877275538400
p method str #=> 69877275538400
この結果から分かりますが、上記の変数 str と obj は同一のオブジェクトを指しています。
したがって、変数 obj に対して破壊的なメソッド(オブジェクト自体を変更するメソッド)を使うと
str が指しているオブジェクトも同一ですから、objに対して行った操作が反映されている、というわけですね。
あってますか?
あと、Stringオブジェクトの内部表現については詳しくしりません。
Rubyのソースを読んでみればわかると思うのですが、まだそこまでのレベルではないので...
スレ汚し失礼しましたです。
0166164
2009/12/13(日) 01:27:10例: s = '123' # sは文字列 '123' を指す
例: s[0], s[1] # sの一文字(バイト)目と二文字目を取得
例: s[1] = '5' # sの一文字目を '5' に変更
>>165
あってるお
内部表現なんて実装次第なんだから
出来ることを正確に把握するほうが大切
0167デフォルトの名無しさん
2009/12/13(日) 01:32:12a = [0, 1, 2]
b = a
b[1] = 10
これでaが何になるのかわからなかった人は横着しないで入門書嫁
0168140
2009/12/13(日) 08:24:28結局クラスでラップする感じになるのかなぁ。
下は意図した通りに動きます。
def State(val)
Monad.new(val)
end
class Monad
def initialize(val)
@val=val
end
attr_accessor :val
end
def f(st)
st.val += 1
end
X = State 1
f(X)
p X.val
0169140
2009/12/13(日) 08:30:000170デフォルトの名無しさん
2009/12/13(日) 08:33:09i=0
Dir.chdir("C:\\"){Dir.glob('**/*'){i+=1}}
p i
=>150660
dir c:\ /s /b /a|find /c /v ""
=>154483
C:\の全ファイルを選択→プロパティのファイル数+フォルダ数
=>153390
1〜2違うどころではないんだが・・・('A`)
0171デフォルトの名無しさん
2009/12/13(日) 09:22:12DOSのコマンドを知らないから憶測だけど、
"."と".."を含めてる含めてないとか?
0172デフォルトの名無しさん
2009/12/13(日) 09:40:23日本語ファイル名が膨らまれているとか
0173デフォルトの名無しさん
2009/12/13(日) 11:00:490174デフォルトの名無しさん
2009/12/13(日) 11:22:02∅
0175デフォルトの名無しさん
2009/12/13(日) 11:44:38とすると、
"\202\240"
8進数で返ってくるのでわかりにくいです。
16進数で帰ってきて欲しいのですが、どうすればいいのでしょうか?
0176デフォルトの名無しさん
2009/12/13(日) 12:05:56class String; def inspect; "\""+ self.each_byte.map{|c| "\\x%02x" % c }.join + "\""; end; end
0177デフォルトの名無しさん
2009/12/13(日) 12:15:41あと?\と?"は別扱いでとか考え出したら面倒くせええ
0178デフォルトの名無しさん
2009/12/13(日) 12:17:32それ、他のオブジェクトをinspectするときに影響が出ちゃわない?
0179デフォルトの名無しさん
2009/12/13(日) 13:03:51class String
alias _inspect inspect
def inspect
self._inspect.gsub(/\\(\d+)/){ "\\x{%02x}" % $1.oct }
end
end
0180デフォルトの名無しさん
2009/12/13(日) 13:06:370181デフォルトの名無しさん
2009/12/13(日) 13:40:29Rubyを関数電卓代わりに使いたいんですけど
0182デフォルトの名無しさん
2009/12/13(日) 13:44:29irb でよければ _ だと思う
0183デフォルトの名無しさん
2009/12/13(日) 13:44:54irb
irb> 1+2
3
irb> _ +4
7
まあ返り値ならなんでもいいんだけど
irb> Time.now
Sun Dec 13 13:40:19 +0900 2009
irb> _.year
2009
0184デフォルトの名無しさん
2009/12/13(日) 13:48:02できればirbじゃなくても使いたいんですが無いですか
0185デフォルトの名無しさん
2009/12/13(日) 13:52:21@かなにかに保持してくれるといいと祈り続けて早10年
0186デフォルトの名無しさん
2009/12/13(日) 14:08:15俺もそれ考えたけど"\\1000"とかで困る
0187デフォルトの名無しさん
2009/12/13(日) 15:24:26こうするのが一般的?
p "あ".unpack("H*")
0188デフォルトの名無しさん
2009/12/13(日) 18:12:58実行時に呼び出すメソッドを切り替えたいのです。
0189デフォルトの名無しさん
2009/12/13(日) 18:15:34send, evalなど
0190デフォルトの名無しさん
2009/12/13(日) 18:24:48ありがとうございます。
0191デフォルトの名無しさん
2009/12/13(日) 18:25:330192デフォルトの名無しさん
2009/12/13(日) 18:49:28適切に漢字コードを指定しておけばちゃんと日本語表示されるんじゃないの?
$KCODE = 'S'
p "あ"
> "あ"
文字じゃないバイナリ列とか表示させるときに16進文字列がいいのなら
そういう出力メソッドを作るなりすれば
0193デフォルトの名無しさん
2009/12/13(日) 19:07:54あと $KCODE は 1.9 じゃ廃止だ
0194デフォルトの名無しさん
2009/12/14(月) 01:00:47def f1 end
def f2 end
・・・ってかんじでメソッドがたくさんあったときに
module_function :f1,:f2,...
って全部書くしか、外からアクセスする方法はないでしょうか?
end
0195デフォルトの名無しさん
2009/12/14(月) 01:05:210196デフォルトの名無しさん
2009/12/14(月) 01:12:46Hoge::f1
というアクセスだけ許したいのですが・・・
いちいち書くのは保守が面倒だと思ったので。
いま考えてるのは
module_function self.methods.join(' ') #未完成
みたいな怪しい方法です。
0197デフォルトの名無しさん
2009/12/14(月) 01:20:55def m1; "m1"; end
extend M
end
M.m1 #=> "m1"
0198デフォルトの名無しさん
2009/12/14(月) 01:22:36ありがとうございます。
0199デフォルトの名無しさん
2009/12/14(月) 05:51:450200デフォルトの名無しさん
2009/12/14(月) 06:07:46リファレンスより
If used with no arguments,
subsequently defined methods become module functions.
モジュール定義の頭に module_function と引数なしで書いておけば
以後に定義するメソッドにはすべて module_function が適用される。
public, private とかと同じだよ。
0201デフォルトの名無しさん
2009/12/14(月) 06:28:54メイン関数って
スクリプトを実行した時に処理系が最初に呼び出すメソッド、という意味?
そういう意味なら、書けない、でFA
そんな取り決めないし
0202デフォルトの名無しさん
2009/12/14(月) 07:36:02def main() しとけばRubyがエントリポイントとして呼んでくれる、とかいうことはないよ
ただ if __FILE__ == $0 ... って常套句を使って少し似たようなことはできる
0203デフォルトの名無しさん
2009/12/14(月) 08:32:24ruby -e 'p self'
0204デフォルトの名無しさん
2009/12/14(月) 08:53:07if __FILE__ == $0
main
end
って書いてたな
0205デフォルトの名無しさん
2009/12/14(月) 11:18:57これでもいいなぁ。
ttp://ruby-doc.org/core/classes/Module.html#M001642
ですね。
初心者はドキュメントのどこを見ればいいかも分からないので、とても助かります。
0206デフォルトの名無しさん
2009/12/14(月) 11:43:32いろんなソース読んだ限り、
Rubyではこんな感じで書いている人が多い。俺も習ってる
class Application
def initialize
end
def run
# ここにメイン処理
end
end
if __FILE__ == $0
Application.new.run
end
0207デフォルトの名無しさん
2009/12/14(月) 13:15:180208デフォルトの名無しさん
2009/12/14(月) 13:29:310209デフォルトの名無しさん
2009/12/14(月) 13:30:080210デフォルトの名無しさん
2009/12/14(月) 13:33:57そのときにその人に直してもらうことにして $0 は使ってもよし
$PROGRAM_NAME はバージョンによらず使えるんだっけ?
0211デフォルトの名無しさん
2009/12/14(月) 13:38:35引数があれば引数で指定したファイルに
引数がなければ標準出力(もしくはエラー出力)に文字列を出したい場合はどのように書いたものでしょうか?
0212デフォルトの名無しさん
2009/12/14(月) 13:46:340213デフォルトの名無しさん
2009/12/14(月) 13:48:20$stdout = File.open ARGV[0]
end
こんな感じニカ ?
0214デフォルトの名無しさん
2009/12/14(月) 13:51:15if ARGV.length > 0
f = open(ARGV[0], "w")
else
f = $stdout
end
f.write "hello"
0215デフォルトの名無しさん
2009/12/14(月) 13:52:13def output
if filename = ARGV[0]
File.open(filename, "w"){|f| yield f }
else
yield $stdout
end
end
output{|io| io.write "a"}
closeめんどくせえ
0216デフォルトの名無しさん
2009/12/14(月) 13:55:43うむ
$stdout.close がIOError で拒否られたときは軽く眩暈がした
0217デフォルトの名無しさん
2009/12/14(月) 17:25:48個々のプログラムでそういうことをするより
シェルのリダイレクトやパイプを使いなさいと言いたいのだが
出力先をプログラムの引数として受け取らなければならない理由はなんだろう?
0218デフォルトの名無しさん
2009/12/14(月) 18:09:37たとえば wget
0219211
2009/12/14(月) 19:36:53ありがとうございます、ありがとうございます
いろいろ方法ありますね。
>>217
事の発端は、最初は標準出力に出してリダイレクト(?でしたっけ)でファイルに書いていたのですが、
ファイルには出したくないBenchmarkとかで計測した結果も表示したくなってそうすると、
どうしたものかって感じになりました。
こういう時って計測結果などはエラーに出せばいいもんですかね?エラーに出していいものかどうか。
>>218
wgetは引数でファイル指定でしたっけ
0220デフォルトの名無しさん
2009/12/14(月) 20:14:480221デフォルトの名無しさん
2009/12/14(月) 20:19:22時間の計算するにはどのクラスを使えばいいでしょうか?
具体的には時間の差分を加算したりしたいのです。
例えば、
elapsed_time += Time.local(2008,12,14,1,50,10) - Time.local(2008,12,10,1,50,10)
のような感じ(実際にはTime.localの中身は可変)
elapsed_timeをTimeにする場合だと初期化にTime.at(0)しても Thu Jan 01 09:00:00 0900 1970 になったり、
0からの時間を考えられていないようなのです。
0222デフォルトの名無しさん
2009/12/14(月) 20:24:17基本的には「ない」
61s が 1m1s になるような、秒数のみを表すクラスというようなのは標準では存在しない
0223デフォルトの名無しさん
2009/12/14(月) 20:25:23Time.at(0).to_i
0224デフォルトの名無しさん
2009/12/14(月) 20:26:07そういうことか、>>223は忘れて
0225221
2009/12/14(月) 20:35:18ないですかー。
何が困るかというと、加算した差分の時間を例えば書式で出力するときにstrftimeみたいなのを自前で書かないといけないってことですよね。
誰かそういうの作ってないか探してみたんですがどうも無いようで・・・。
active_supportとかの日付の拡張あたりでなんとかならないもんですかね。
0226デフォルトの名無しさん
2009/12/14(月) 20:49:16sec = time % 60
min = (time / 60) % 60
hour = (time / (60 * 60)) % 24
day = time / (24 * 60 * 60)
puts "%dday %d:%d:%d" % [day, hour, min, sec]
こんなんでいいか?
0227221
2009/12/14(月) 21:01:02ずばりそのまま書いてくださってありがとうさんです。
使わせていだきます。
ActiveSupport使ってもこんな感じですか。かわらないやw
time = 100000
sec = time % 60
min = (time / 1.minute) % 60
hour = (time / 1.hour) % 24
day = time / 1.day
puts "%dday %d:%d:%d" % [day, hour, min, sec]
0228デフォルトの名無しさん
2009/12/14(月) 22:30:38立ち消えしてるのかな、これは。
0229デフォルトの名無しさん
2009/12/14(月) 22:34:400230デフォルトの名無しさん
2009/12/14(月) 22:36:53.NET好きな人はIronRuby使ったらいい
0231デフォルトの名無しさん
2009/12/15(火) 00:52:12Rubyを関数電卓代わりに使いたいんですけど
0232デフォルトの名無しさん
2009/12/15(火) 00:58:100233デフォルトの名無しさん
2009/12/15(火) 01:01:41よくわからんけど「Ruby 数値積分 微分」でぐぐってみた
ttp://jp.rubyist.net/magazine/?0006-RLR
こっちは結構すごそうだぞ
ttp://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/39950
0234デフォルトの名無しさん
2009/12/15(火) 01:01:55詳しくは見ていないけど、数値積分や微分はあるみたい。
ただし、最後のリリースが約2年前というのが気掛かり。
十分枯れているのだろうけれど、新しめのRubyで動くかは不明。
ところで、本格的な数式処理なら、Maximaとか使ったほうがいいんじゃない?
0235デフォルトの名無しさん
2009/12/15(火) 01:05:330236デフォルトの名無しさん
2009/12/15(火) 01:43:08導入めんどくさそうですけど頑張ってみます
0237デフォルトの名無しさん
2009/12/15(火) 02:03:40でなければ、カシオの計算センターとか。
自前のコードからコールしたいなら、ついでにそっちも自分で書いてしまう。
てのは、いかがでしょう。
0238デフォルトの名無しさん
2009/12/15(火) 06:35:31> ファイルには出したくないBenchmarkとかで計測した結果も表示したくなって
標準ライブラリの Logger を使ってみるというのは?
http://jp.rubyist.net/magazine/?0008-BundledLibraries
0239デフォルトの名無しさん
2009/12/15(火) 09:20:540240デフォルトの名無しさん
2009/12/15(火) 09:53:38カジュアルなデータ計算をさせることが期待されるプログラミング言語のトップグループにいることは間違いない
専門数値計算ソフトやC(やJava)を持ち出さなくてもいい程度の計算なら、もっと気楽にできてもいい
高校や大学1年教養の宿題をうっかり解けてしまうような、そんな用途があってもいいはず
0241デフォルトの名無しさん
2009/12/15(火) 10:06:280242デフォルトの名無しさん
2009/12/15(火) 10:09:150243デフォルトの名無しさん
2009/12/15(火) 10:20:550244デフォルトの名無しさん
2009/12/15(火) 10:28:350246デフォルトの名無しさん
2009/12/15(火) 15:56:000247デフォルトの名無しさん
2009/12/15(火) 18:38:35ワンライナーで時間の計算をする時に24時間以内なら
ruby -rtime -e "a=Time.parse('09:08:20')-Time.parse('01:40:02');puts Time.at(a).utc.strftime('%H:%M:%S')"
とかしたりしますな
0248デフォルトの名無しさん
2009/12/15(火) 18:47:01でも自己責任の域を出れない
0249デフォルトの名無しさん
2009/12/15(火) 18:54:35puts "私は#{name}です"
nameに日本語を入力するとエラーが出てしまいます
C:/My Documents/g/Ruby/test.rb:4:in `<main>': incompatible character encodings: ASCII-8BIT and
Windows-31J (Encoding::CompatibilityError)
これはどういったエラーなんでしょうか?
0250デフォルトの名無しさん
2009/12/15(火) 19:03:50初心者は Ruby1.9 使うなってこれだけ言われてるのになんでわからんのだエラー
0251デフォルトの名無しさん
2009/12/15(火) 19:08:17Windows-31Jがロードできたら標準入力もそっち使うようになってなかったっけ
どういうときにそんなことになりえるのか知りたい、誰か教えて
0252デフォルトの名無しさん
2009/12/15(火) 19:08:20■ このスレッドは過去ログ倉庫に格納されています