[2000/10/03]

ruby

every

IRCの%rubyでeveryが話題になってたので作ってみました。

Arrayで実装としては[ruby-list:20933][ruby-list:20932]がありました。

everyでArrayを返すとArray#collectが使われてあんまりうれしくないのと、ArrayのArrayを作るのにコストがかかりそう&最初にeachが終わるのを待たないといけない、ということがあって独自のクラスを返すようにしてみました。

module Enumerable
  class Every
    include Enumerable

    def initialize(enum, n)
      @enum = enum
      @n = n
    end

    def each
      ary = []
      @enum.each do |i|
        ary << i
        if @n == ary.size
          yield(ary)
          ary = []
        end
      end
      unless ary.empty?
        ary[@n-1] = nil
        yield(ary)
      end
    end
  end
  def every(n)
    raise ArgumentError, "out of range" if n <= 0
    Every.new(self, n)
  end
end

[1,2,3,4,5,6,7,8,9,10].every(4).each { |x| p x }
    #=>[1, 2, 3, 4], [5, 6, 7, 8] ,[9, 10, nil, nil]
p [1,2,3,4,5,6,7,8,9,10].every(3).collect { |x| x.reverse }
    #=>[[3, 2, 1], [6, 5, 4], [9, 8, 7], [nil, nil, 10]]
p [1,2,3,4,5,6,7,8,9,10].every(2).collect { |x,y| x+y }
    #=>[3, 7, 11, 15, 19]

これを作ってる時に経験したバグ。

最後のary.clearのバグは、eachから見るとyieldにあげちゃったオブジェクトを使い回そうとしたのがいけなかった。yieldで呼ばれるブロックから見ると、前に受け取ったブロック引数をどっかにとっておいたらいつの間にか変わっていておかしなことになる。

C言語版をknuさんが作ってましたが、同じはまったそうです。

yieldに渡したものを後で変更すると変なことになる、というのは落とし穴かもしれません。

arity

[ruby-dev:9930]のあたりのスレッド参照。適当にまとめると以下の通り。

to_ary

[ruby-list:24985]にはないのに[ruby-list:24986]にはto_aryのことが書いてある。

[2000/10/07]

ruby

ActiveScriptRuby

COM Meets Rubyからダウンロード。

拡張子がbinなのがかなり謎。msiっていうのがダメならlzhとかzipとかcabとかでmsiファイルをアーカイブすればいいのに。

ってここに書いても変わらなかったら直メールはあんまり好きじゃないけどメールするかも。

FAQ

[ruby-list:25325]の「だけど、メーリングリストのアーカイブから検索してやっとみつかる(かもしれない)のをFAQと言われてもなぁ。」をみて思ったのですが、FAQって何度もきかれているからFAQであってQ&A集としてまとめられている必要はないはず。

だからできたばかりのところでQ&A集をFAQという名前で公開していたらできたばかりなのにそんなに質問されてますか:-)とかかかれてしまうと思うのです。

rbのアイコン

ActiveScriptRubyを入れた影響でrbのアイコンが変わっていた。 ActivePerlの小さくて黄色いのに比べて大きくていい感じ。

[2000/10/08]

ruby

String#tr

ターミナルが化けるのでコントロールコードの除去をしようとした時の試行錯誤の記録。

最終的にはこれで動作確認をした。

a=(0x00..0x7F).collect{|i|i.chr}.join('').gsub('[\x00-\x1F\x7F]', '')
b=(0x00..0x7F).collect{|i|i.chr}.join('').tr("\x00-\x1F\x7F", '')

puts "[[#{a}]],[[#{b}]],#{a==b}"

gsubの第一引数は文字列を渡すと正規表現にコンパイルされるのでそこで\xの処理がされているみたい。

[2000/10/13]

カウンター

ここの9500踏む。

ruby

HotLinks

index.htmを更新しないと更新と見なされないみたい。

Thread

Ruby 1.6.1までのThreadってバグ多いかも。

formula

ruby-formulaにequal?の説明を追加した。

safe eval

安全にevalするために専用のスレッドを使って$SAFE = 4で やってみました。

すると同じメソッド内部のローカル変数(以下の例だとresultなど)が いじれてしまったので、別メソッドでbindingを作るようにしました。

それでもexitの代わりにraise SystemExitで終了できてしまったり raise SignalExceptionで終了できたりしてしまったので、 ScriptError, StandardErrorだったのをExceptionに変更しました。

これで安全なのでしょうか?

Thread.abort_on_exception = true

s = ARGV.shift

class Eval
  def sandbox
    @binding = binding
    self
  end

  def evaluate(s)
    binding = @binding
    result = ''
    th = Thread.start do
      $SAFE = 4
      begin
        result = eval(s, binding).to_s
      rescue Exception
        result = $!.to_s
      end
    end
    th.join
    puts result
    self
  end
end

Thread.start do
  e = Eval.new
  e.sandbox
  e.evaluate(s)
end

gets

IPA

<URL:http://www.miti.go.jp/kohosys/press/0001021/2/1012it563.html>の一番下にRubyが。 それから一番上にAirWebが。 他に知ってた人はやまざき@BinaryTechnologyの山崎さんかな。

Perl

mとs

//mと//sの説明が紛らわしい。

修飾子 意味
m      文字列を複数行として扱う
s      文字列を単一行として扱う
プログラミングPerl改訂版 79ページ より

似たような説明だから逆の意味かと思っていたら全く関係なかった。

修飾子 意味
m      ^ $ が改行にマッチするようになる。
s      . が改行にマッチするようになる。

ということでそれぞれ影響するものが違います。 ちなみに逆の意味なのは(?-m)や(?-s:...)みたいに-をつけたもの。

[2000/10/14]

ruby

PStore#abort

PStore#abort(@db.abort)のつもりでObject#abort(abort)を使ってしまって、謎の突然終了で悩んでしまった。

each_line

行の途中までしか送られてこないことがあるので以下のようなループで行毎にしているが、/pはobsoleteなのでどうにかしたい。

rest = ''
@nif.waitfor({"Prompt" => @options["Prompt"],
               "Timeout" => timeout}){|c|
  yield c if iterator?
  if rest+c =~ /^(.*\n)([^\n]*)$/p
    rest = $2
    $1.each_line {|line|
      received(line)
    }
  else
    rest.concat c
  end
}

[2000/10/16]

perl

昨日%rubyでなぜかperlの話が盛り上がっていた。

<URL:http://pluto.im.uec.ac.jp:1800/~sekita-n/jdocs/perl2ruby.html>の「($A[5][1] は実際には $A->[5]->[1]の略記法)」が間違っている。

% perl -e '$a = [[1, 2], [3, 4]]; print $a[0][0], "\n";'
% perl -e '$a = [[1, 2], [3, 4]]; print $a->[0][0], "\n";'
1
% perl -e '@a = ([1, 2], [3, 4]); print $a[0][0], "\n";'
1
%

->が省略できるのは[][]の様な括弧の間のところだけということを再確認。
それからv5.6.0では[]->()も->が省略できると言うことを知った。
5.005_03だと省略できなかったのでforeach修飾子と同じでまだ汎用のスクリプトで使うのには向かないと思う。

[2000/10/17]

ruby

finalizer

IRCの%rubyより。 1.4と1.6の両方で使えるようにするにはrequire 'final'すればいいらしい。 1.6ではfinal.rbは空になっている。

pitfall

Rubyの落とし穴をまとめてみた。

[2000/10/19]

ruby

mp3ls

mp3lsのネタをいただいてRubyにしてみる。 mp3ls.cは"r"で開いてますが、バイナリモードで開かなくても大丈夫なんでしょうか? とりあえずパクリ元のcopyrightも入れておこう。

#!/usr/bin/ruby
=begin
= copyright
== ruby version copyright
copyright (c) 2000 Kazuhiro NISHIYAMA <zn@mbf.nifty.com>
== original C version copyright
/*
 * mp3ls - printing ID3 of MPEG1 Audio Layer-3 file
 * Version 0.0.2
 * Copyright (C) 2000 Yoichi Imai <yoichi@silver-forest.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 * http://www.gnu.org/copyleft/gpl.html
 */
=end

require 'nkf'
nkf_arg = '-e'

ARGV.each do |filename|
  File.open(filename, 'rb') do |f|
    f.seek(-128, IO::SEEK_END)
    id3 = f.read(128)
    tag, title, artist, album, year, comment, genre =
      id3.unpack('Z3 Z30 Z30 Z30 Z4 Z30 C')
    title = NKF.nkf(nkf_arg, title.strip)
    artist = NKF.nkf(nkf_arg, artist.strip)
    puts "#{filename} / #{title} / #{artist}"
  end
end

[2000/10/21]

'b'

<URL:http://members.linuxstart.com/~sunnyone/cgi-bin/diary/?200010b&to=200010194#200010194>

Windowsとかでの動作は全く考えてませんでしたか。 RubyならWindowsでも…と思ったけどnkf_argはいちいち書き換えないとダメか。 書き換えやすいように2つあったのをまとめて上に持っていったわけだけど。

[2000/10/23]

Ruby

落とし穴への追加候補?

[2000/10/24]

Ruby

RDでshebang

rd2がshebang(ファイルの最初の#!の行)に対応したら便利かも、とふと思った。

Vine Linux 2.0

CVSでとってきたのを自分でmakeしたrubyでpeeraddrが変だったので、ruby -v -rsocket -e 'port=12121;p TCPServer.open(port).accept.peeraddr'&sleep 1;telnet localhost 12121って感じでいろんなので試してみました。

最初の行はDebian/GNU Linux 2.2 (potato)でmakeしたもの。 2行目以降はVine Linux 2.0標準のgcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)でmakeしたもの。 VinePlusのrpmのruby.specを参考にしてconfigureにオプションを追加していったところ以下のような結果に。 xxxxのところは毎回変わるポート番号。

["AF_INET", xxxx, "localhost", "127.0.0.1"]             ruby 1.6.2 (2000-10-21) [i586-linux]
["unknown:10", xxxx, "localhost", "::ffff:127.0.0.1"]   configure --prefix=/tmp/$USERのみ
[false, xxxx, "localhost", "::ffff:127.0.0.1"]          同1.4.6
["AF_INET6", xxxx, "localhost", "::ffff:127.0.0.1"]     --enable-ipv6を追加
["unknown:10", xxxx, "localhost", "::ffff:127.0.0.1"]   --with-lookup-order-hack=INETを追加
["AF_INET", xxxx, "localhost.localdomain", "127.0.0.1"] --enable-ipv6と--with-lookup-order-hack=INETを追加

結局--enable-ipv6と--with-lookup-order-hack=INETがあれば正常になるということがわかりました。

[2000/10/25]

Ruby

bang method

<URL:http://kirara.prec.kyoto-u.ac.jp/~tam/diary/#10-24:2>

bang methodは変更しなかったときにnilを返す、っていうのも落とし穴候補かも。 while str.gsub!(/(\d+)(\d{3})/){"$1,$2"};endみたいなことをするときには便利な仕様なんだけど、メソッドチェーンをするのには向かないなぁ。

ちなみにsortもuniqも実行時間は要素数に比例するので、sort.uniqよりもuniq.sortの方が速いです。

ソート済みを前提としたuniqを別に用意するとか、いっそのことsort_uniqなんて作ってみると便利かもしれない。

Rubyプログラミング入門

今日が発売日のはず。 とりあえず途中まで読んだのでerrataっぽいのを書いてみた。

[2000/10/26]

Ruby

shebang

<URL:http://www2.pos.to/~tosh/ruby/diary/2000/10/c.html#sec25_6>

ファイル「hoge」の1行目が「#!foo bar」だったら「hoge arg」で「foo bar hoge arg」が起動されると思います。 対応というのは「#!/usr/bin/ruby -S rd2 -someoption」とか書いてたら-someoptionをコマンドラインに指定されたのと同じように解釈してほしいと言うことだったのですが、実際に実行可能と言うことまで考えるとhogeとargの区別(./hoge argのつもりで起動されたのかrd2 hoge.rd arg.rdのつもりで起動されたのか)が難しいかも。

[2000/10/26]

他の日記とか

DCさくら

<URL:http://www.weatherlight.org/~crouton/journal/?200010C#200010271>

昔はダウンロードキャプターさくらという名前だったけど正式名称がver.1.50からDCさくらになったはず。

[2000/10/30]

Perl

リファレンス

<URL:http://member.nifty.ne.jp/phinloda/index.htm>の2000年10月28日の 「perlで $foo{key1}{key2} を配列とみなして push する方法というくだらない所でひっかかっていたが、聞いてみたら簡単だったのでショック。」

Perlのリファレンスってほとんど使ったことないので勘違いしてるかもしれませんが、基本的にはスカラーとして扱うときは$hoge{foo}[bar]みたいに後ろに括弧をつけていくだけで良くて、配列とかハッシュとして扱いたいときは@{$hoge[foo]{bar}}みたいに全体を{}でくくって前に@や%をつければ良いと理解しているんですが。

Ruby

String#delete

str.tr("\x00-\x1F\x7F", '')ってやってたのをstr.delete("\x00-\x1F\x7F")に修正。

Symbol ←→ String

SymbolからStringへの変換はSymbol#id2name。StringからSymbolへの変換はString#intern。

%W(・・・)

%wと%q、%Wと%Qという感じで%Wっていうのも使えるようにしたら便利かも、と思ったのですが、エスケープがややこしくなるのであんまり便利じゃないかも。


上へ indexへ
copyright © 2000 ZnZ