2006-03-01から1ヶ月間の記事一覧

イテレータ変換

内部イテレータを外部イテレータに変換します。 あ、えーと、一言で言えばeachをnextに変換するということです。 each-ableなコレクションを渡してIteratorオブジェクトを作ります。 callccを使います。 最後に達したときにはnextはnilを返し、自動的にrewin…

String#to_f

Rubyで文字列を浮動小数点数に変換するには、String#to_fメソッドを使います。詳しくは、ri String#to_f参照。 p "3.14".to_f #=> 3.14 p "314e-2".to_f #=> 3.14 p "3.14ABCDEF".to_f #=> 3.14 p "Rubyco3.14".to_f #=> 0.0

日本語文字列の文字数 / $KCODEよりも-Kオプションで

artonさんのところで話題になっていたので、わたしも書いてみました。無駄に複雑にしています。てへ♪ でも、each_charって便利ではないでしょうか。 $KCODE = 'SJIS' class String def each_char scan(/./) do |c| yield(c) end end def char_count n = 0 ea…

引数まとめて引き渡し

アスタリスク(*)を使うと、メソッドにやってきた引数をまとめて他のメソッドに引き渡せます。…って以前も書いたけれど…、いいや♪ def hyuki(*args) p args end def rubyco(*args) hyuki(*args) end rubyco(3) rubyco(3, 1) rubyco(3, 1, 4)実行結果です。 [3…

aliasとmethodメソッド

methodで得られるメソッドオブジェクトは毎回作られるみたいです(object_idが異なるから)。equal?で比較するとfalseになりますが、==で比較するとtrueです。 aliasで名前を変えても、==で比較するとtrueです。 def rubyco end p method(:rubyco).object_id #…

compact

Array#compactは、配列中のnilを削除した配列を新たに作って返します。compact!は(いつものように)破壊的メソッドです。 a = [ 'A', nil, 'B', 'C', nil, nil, 'D'] p a #=> ["A", nil, "B", "C", nil, nil, "D"] p a.compact #=> ["A", "B", "C", "D"] p …

newを書かずにインスタンス生成

newが嫌いな理由 -- リテラル好き好きを読んで、newを書かずにインスタンス生成する実験をRubyでやってみます。 class Person def initialize(name) @name = name end def hello puts "Hello, #{@name}!" end end def Person(*args) Person.new(*args) end #…

aliasとメモ化

お皿を洗っているときに「aliasで元のメソッドを保存しておくこととメモ化は相性が良い」と気づいたので、さっそくコーディングしてみました。まずは関数的に実装します。 def fib(n) print "." if n <= 1 1 else fib(n - 1) + fib(n - 2) end end def fib_t…

getsとreadline

IO#getsとIO#readlineでは、EOFに達したときの振る舞いが異なります。getsはnilを返しますが、readlineはEOFErrorをraiseします。 まずはgetsを試します。 while line = DATA.gets puts line end __END__ 1 22 333実行結果です。 1 22 333次にreadlineを試し…

負の添字

配列に負の添字を与えると、「後から数えた」要素を意味します(最後の要素は-1番目)。 a = [0, 1, 2, 3] p a[-1] #=> 3 p a[-2] #=> 2 p a[-3] #=> 1 p a[-4] #=> 0 p a[-5] #=> nil

Array.newとブロック

初期値を定めるために、Array.newにブロックを与えることができます。 a = Array.new(7) do |i| (?A + i).chr end p a #=> ["A", "B", "C", "D", "E", "F", "G"]上と同じことは、以下のプログラムでも書けます。 a = ("A".."G").to_a p a #=> ["A", "B", "C"…

Module#freeze

Rubyでは、Module#freezeを使うと、クラスやモジュールが変更できなくなります。 class String def rubyco end end String.freeze class String def rubyco #=> can't modify frozen class (TypeError) end end

ブロックはProc

ブロックとして渡されてくるのはProcオブジェクトです。proc { } や lambda{ }もProcオブジェクトです。ただ { } と書くとHashオブジェクトですね。 def p_block(&block) p block.class end p_block { } #=> Proc p(proc { }.class) #=> Proc p(lambda { }.c…

Method

RubyのMethodクラスは、メソッドのクラスです。 Methodオブジェクトは、メソッドだけではなくそのレシーバも特定していることに注意。 class String def rubyco puts "#{self}" end end "Hello!".rubyco #=> Hello! "Good!".rubyco #=> Good! m = "Nice!".me…

書籍『オブジェクト指向スクリプト言語Ruby』

この「rubyco(るびこ)の日記」を書き始めて、毎日『オブジェクト指向スクリプト言語Ruby』をはじめから少しずつ読んでいます。今日まででおおよそ半分読みました。これは良書ですね。

Rubyに++がない理由

今日の衝撃経由、ruby-list:5323にて。 「(Rubyに++がないのは)++の動作が本質的に「変数を操作する」ものであるため」とのこと。 なるほど。 変数はオブジェクトではない ++は += 1 すなわち「代入操作」である 代入操作はオブジェクトに対する操作ではなく…

モジュール練習

以下で練習として作ったモジュールReadableは、readline, readsome, readallを定義しますが、すべてreadcharに立脚します。readcharはクラスの側で実装されることを期待します。 module Readable def readuntil s = nil while c = readchar break if yield(c…

ρヒューリスティック

大きな数の因数を発見的に求めるρ法(Pollardのρヒューリスティック)をRubyで実装しました。 # 2個の素数の積を因数分解する def factor_two(given) start = Time.now one = rho(given) another = given / one elapsed = Time.now - start puts "#{given} =…

Marshal

Marshal.dumpとMarshal.loadでオブジェクトのマーシャリングができます。 class Rubyco def hello puts "Hello!" end end org = Rubyco.new org.hello #=> Hello! dumped = Marshal.dump(org) p dumped #=> "\004\010o:\vRubyco\000" obj = Marshal.load(dum…

シンボルの作り方

Rubyのシンボルは、%s( ... ) でも作れます。 def pr(s) p s p s.class end pr :rubyco pr :"rubyco" pr %s(rubyco)実行結果です。 :rubyco Symbol :rubyco Symbol :rubyco Symbol

include

モジュールをincludeすると、モジュールのメソッドが使えます。selfもしかるべく扱われます。 module RubycoModule def p_self p self end end class RubycoClass include RubycoModule end RubycoClass.new.p_self #=> #<RubycoClass:0x298f080></rubycoclass:0x298f080>

private

privateなメソッドはレシーバを省略しないと呼び出せません。 class Rubyco def secret puts "..." end private :secret end Rubyco.new.secret #=> private method `secret' called for #<Rubyco:0x298f1b8> (NoMethodError)レシーバを省略すれば呼び出せます。 class Rubyco </rubyco:0x298f1b8>…

ancestorsとsuper

Module#ancestorsを修正するとsuperは変化するか、という話題です。 class GrandParent def hello; puts "GrandParent"; end end class Parent < GrandParent def hello; super; puts "Parent"; end end class Child < Parent def hello; super; puts "Child…

gzipファイルを扱う

Zlib::GzipWriterを使うと、Rubyでgzipファイルが作れます。 詳細は、ri Zlib::GzipWriterを参照してください。 require 'pathname' require 'zlib' Zlib::GzipWriter.open('rubyco.gz') do |f| 1000000.times do f.write "Hello!" end end p Pathname.new("…

gzipファイルにマーシャリング

オブジェクトのマーシャリングをするときに圧縮してしまえ、という話題です。 require 'pathname' require 'zlib' a = Array.new a[0], a[1000] = "Hello", "Rubyco" p a[0] #=> "Hello" p a[1000] #=> "Rubyco" Zlib::GzipWriter.open('rubyco.gz') do |f| …

pack→gzip→dump

gzipする前にpackしてみました。 ※なぜZlib::ZStreamを使わないかというと、まだ使い方を理解していないからです。てへ♪ require 'pathname' require 'zlib' a = Array.new(10000) do rand(10000) end open('raw_data', 'wb') { |f| f.write(Marshal.dump(a)…

method_added with callcc

Module#method_added, Module#method_removedを使うと、メソッドの追加(定義)と削除を監視できます。 class Rubyco def self.method_added(sym) puts "method_added(#{sym})" end def self.method_removed(sym) puts "method_removed(#{sym})" end def rub…

Digest::MD5.hexdigest

RubyのプログラムからファイルのMD5値を得てみました。もっとも単純な方法は、Digest::MD5.hexdigestを使う方法です。 詳しくはrefe Digest::Baseあたりを調べましょう。riでは見つかりません。 require 'pathname' require 'digest/md5' p = Pathname.new("…

singleton_method_added

Object#singleton_method_added, Object#singleton_method_removedを使うと、特異メソッドの追加と削除を監視できます。 class Rubyco def self.singleton_method_added(sym) puts "singleton_method_added(#{sym})" end def self.singleton_method_removed(…

set_trace_func

set_trace_funcを使ってProcオブジェクトを登録すると、インタプリタの動きにあわせてそのオブジェクトが呼び出されます。 set_trace_func proc { |event, file, line, id, binding, klass| print "#{event}, #{file}, #{line}, #{id}, #{binding}, #{klass}…