トップ «前の日(09-17) 最新 次の日(09-19)» 追記

2003-09-18

_ ネットによるエンパワー

http://blog.cnetnetworks.jp/umeda/archives/000683.html

個人的には少し懐かしいこの単語。内容には大きく共感します。

考えたらテレビの世界ではけっこう前から起きてますよね、この現象。「モデル → 女優、歌手」みたいな流れや「スポーツ選手 → バラエティ、レポーター」みたいな流れはすでにポピュラーなわけで。もちろん本当にプロより優れている人が埋もれていたというケースはそれほど多くないとは思いますし、前提としては他の世界である程度以上有名ということが多いとは思いますが、人材の流動化という意味ではいわゆるカタギな世界に比べるとずいぶん進んでますよね。

いろんな成功パターン、成功プロセスがあるはずだ、と思いながら行きますかね。

Tags: Net Community

2004-09-18

_ 東北人は豆腐をよく食べるからバストが大きい

from ホムクル

へぇ。

でもこの番組ってこういうランキング番組だったか? なんかクイズみたいなのやってなかった? なんかよく分からんなぁ。

  • いちばん喋らないのは青森県
  • 社長が多いのは福井県(お、新潟も多いのか)
    • 社長が多いのは辛抱強いってことよりも仕事が少ないんじゃないか?と思うのが地元の素直な感想ですが。。。

あ、ホムクル最終回だ。それでこんな変わった構成だったのか?

Tags: TV 日々

_ Olivetti はもうパソコン作ってない

伊Olivetti社がパソコン部門を売却 (PC Watch)

97年の記事ですが。メモしておかないとまた忘れそうで。

Tags: 日々

2005-09-18

_ Perlプログラミング救命病棟確保

ぱらぱらーっと眺めた限りでは perldoc で提供されていたり、あちこちですでに見聞きしたものが多いかな。まとまっているので Perl newbie を卒業したくらいのレベルの人に読ませるにはいいかもしれない。少なくともこれ読んだうえですすんで他人には解読不能なコードを書くことはあるまい。

最近 Perl 書かないようにしてたこともあり、これで復習しよう。

一週間ほどサボります。

Tags: Book Perl

2007-09-18

_ zsh やっぱ戻した

そういえばこの Fink の 4.2.5 は日本語ディレクトリに cd しようとすると落ちるんだった。忘れてた。それで使ってなかったんだ。しくしくしく…。

Tags: Zsh

_ 手作業修正 -> load 完了

svnadmin dump した結果をスクリプトと手作業で編集して svnadmin load するのに成功した。まぁ成功して当たり前なんだけど、一応メモ。使ったのは svn 1.4.2 と Ruby 1.8.5 とエディタ。

svndumpfilter はそんなに使えない

svnadmin dump の結果に対して path で単純なフィルタリングを行う svndumpfilter というものがあるが、これを適用しても特に以下のようなリポジトリレイアウトの場合、あまり役に立たない。

branches/
  各モジュール/
  ...
tags/
  ...
trunk/
  ...

このツールは以下のようなレイアウトになっていて、

モジュール/
  branches/
  tags/
  trunk/
モジュール/
  branches/
  ...
...

ここで言うモジュール単位に分割する際には使える。つまり、リポジトリそのものの操作がのちのち楽なのは後者のレイアウト。

新規にリポジトリを作成する場合はともかく、cvs2svn で既存のリポジトリを変換する場合は何も考えないと前者のレイアウトになってしまうので注意が必要。

※ その他にも cvs2svn は svn:eol-style を native にしてしまうのでクライアントのプラットフォームが混ざっている場合に思わぬ不具合を引き起こす可能性がある。

dump したテキストファイルは mbox のような感じ

なので、mbox っぽいデータを自分でパースしたことのある人ならなんとかなります。XML ではないのでデータの終わりは明示されず、始まりしか明示されないので、始まりの区切りをそこまでのデータの終わりとして機能させれば ok.

ただし改行コードは混ざっているので注意。パースする際に改行コードを無造作に chop しちゃダメ。

タグを打った操作の追跡時に注意が必要

svn copy は特定のパスだけを copy する作業がなかなかやりにくい。これが cvs2svn を使ってリポジトリを変換した際、タグを打つ操作に対応する revision を見るとなるほどと思う。丸ごといちばん上の階層から copy して、不要なパスを delete している。このとき、この delete するパスが存在していないと load の際に失敗する。

つまり、

branches/
  ..
trunk/
  path1/
  path2/
tags/
  ..

というリポジトリがあり、

branches/
  path1/
trunk/
  path1/

のように path1 だけを取り出したいという場合、最初の方の revision で path2 を add する作業をカットしてあると、copy -> delete のコンボ revision の中で path2 を delete するアクションがあってはいけない。

でもまぁ手作業対応もそれなりに可能

今回はまだリポジトリの full dump が 124MB、取り出したい部分の dump ファイルが 26MB で収まっていたので、なんとかエディタで開いてスクリプトで対処しきれなかった余計な部分のカット、逆にスクリプトで取り除きすぎてしまった部分を full dump から戻す作業を行えた。(重かったけど。)ブランチの数もせいぜい数十。

ただこのレベルを越えるとなるともっと精度の高いフィルタが必要だなとは思った。

使ったスクリプト

本当はできるだけ手作業を減らそうと、revision ごとに dump ファイルを分割する機能をつけて、保全した revision の差分を取ってゴニョゴニョ(まだあまり考えていない)する機能をつけようと思っていたのですが、面倒くさくなったので放置です。

実に中途半端な状態ですが、とりあえずバックアップ目的で貼っておきます。なんか使えそうならご自由に。

#! /usr/bin/env ruby

require 'pathname'
require 'logger'

=begin

Subversion の dump ファイルから特定の条件を満たす node および revision
だけの dump ファイルを生成する。

Usage: ruby SCRIPT srcdump > destdump

Revision について
=================

Prop-content-length: は当然ヘッダ部以降 PROPS-END までのサイズ。

Content-length: は Prop-content-length と同じ。この数字は Node の
content-length に影響されない。つまり、Revision の途中で Node がバッサ
リ落ちても影響ない

ただし Node をただ単独で落とすと cvs2svn が作る、丸ごと copy してから要
らないものを削除するという revision に対応できないことがある。

Node-copy* という文字列を見つけたら Revision 丸ごと保存したい。

Node について
=============

Prop-content-length: はヘッダ部以降 PROPS-END までのデータのサイズ
Text-content-length: は PROPS-END 以降次のヘッダまでのデータのサイズ
Content-length: は上の content-length の合計

=end

#
# svnadmin dump した結果を処理するツール
#
module Svndump
  #
  # パースした node および revision に対する共通メソッド
  #
  class Common
    def initialize( loglevel = nil )
      _init_logger( loglevel )

      @curr_rev   = nil
      @curr_node  = nil
      @buf        = []
      @revs       = []
    end

    #
    # Logger の初期化
    #
    def _init_logger( level = nil )
      if ( level.nil? )
        return false
      end

      @logger = Logger.new( STDERR )
      case level
      when 'debug'
        @logger.level = Logger::DEBUG
      when 'info'
        @logger.level = Logger::INFO
      when 'warn'
        @logger.level = Logger::WARN
      when 'error'
        @logger.level = Logger::ERROR
      else # include 'fatal'
        @logger.level = Logger::FATAL
      end

      return true
    end
    private :_init_logger

    #
    # 指定ファイルまたは標準入力から dump ファイルを読み込みあれこれ
    #
    # 行ごとに分割して特徴的なヘッダ行をもとに pre_hook, post_hook を定義
    # chomp() しない。改行コードが混ざっている可能性があるので。
    #
    def read
      while ( line = gets )
        case line
        when /\ARevision-number: ([0-9]+)/
          revision_pre_hook()
          @curr_rev  = $1.to_i
          @curr_node = nil
          revision_post_hook()
        when /\ANode-path: (.*)/
          node_pre_hook()
          @curr_node = $1
          node_post_hook()
        when /\ANode-copy/
          nodecopy_pre_hook()
        end
        @buf.push( line )
      end
    end # of read()

    def revision_pre_hook
    end

    def revision_post_hook
    end

    def node_pre_hook
    end

    def node_post_hook
    end

    def nodecopy_pre_hook
    end

    def clear_rev_buf
      @rev_buf  = []
      @keep_rev = false
    end
    private :clear_rev_buf

    def clear_buf
      @buf      = []
      @storable = true
    end
    private :clear_buf
  end # of class Common

  #
  # dump ファイルを各 revision ごとに分割する
  #
  class Splitter < Common
  end

  #
  # 小さくする
  #
  class Compact < Common
    #
    # コンストラクタ
    #
    def initialize( loglevel = nil )
      super( loglevel )

      @dump_header = true
      @keep_rev    = false
      @rev_buf     = []

      @storable    = true
    end

    #
    # 主処理
    #
    def run
      read()
      after_all()
    end

    #
    # Revision-number の切り替わりのタイミングで呼ばれるメソッド
    #
    def revision_pre_hook
      if ( !@logger.nil? )
        @logger.debug( "in revision_pre_hook() rev #{@curr_rev} node #{@curr_node}" )
      end
      store2rev()
      output_rev()
      if ( @curr_rev == 0 )
        @dump_header = nil
      end
    end

    #
    # Revision-number の行を読んだ瞬間に働く hook
    #
    def revision_post_hook
    end

    #
    # Node-path の切り替わりのタイミングで呼ばれるメソッド
    #
    def node_pre_hook
      if ( !@logger.nil? )
        @logger.debug( "in node_pre_hook() rev #{@curr_rev} node #{@curr_node}" )
      end
      store2rev()
    end

    #
    # Node-path の行を読んだ瞬間に働く hook
    #
    def node_post_hook
    end

    #
    # Node-copy* 行が現れるタイミングで呼ばれるメソッド
    #
    def nodecopy_pre_hook
      @keep_rev = true
    end

    #
    # 全部読み終わった時点で呼ばれるメソッド
    #
    def after_all
      if ( !@logger.nil? )
        @logger.debug( "in after_all() rev #{@curr_rev} node #{@curr_node}" )
      end
      store2rev()
      output_rev()
    end

    #
    # 現在の @buf の内容を保存するかどうか
    #
    def store?
      return ( @keep_rev or @storable )
    end
    private :store?

    #
    # dump header および revision 0 かどうか
    #
    def dump_header?
      return @dump_header
    end
    private :dump_header?

    #
    # @buf_rev の内容を出力する
    #
    # 出力後、クリアもする
    #
    def output_rev
      if ( !@logger.nil? )
        p @curr_rev
        pp @rev_buf
        p "dump_header #{dump_header?}"
        p @rev_buf.size
      end
      if ( dump_header? or @rev_buf.size > 1 )
        @rev_buf.each { |buf|
          puts buf.join()
        }
        @revs.push( @curr_rev )
      end
      clear_rev_buf()
    end

    #
    # @buf の内容を @buf_rev に store
    #
    def store2rev
      if ( !@logger.nil? )
        @logger.debug( "in store2rev() store? #{store?}" )
      end
      if ( store? and @buf.size > 0 )
        @rev_buf.push( @buf )
      end
      clear_buf()
    end

  end # of class Compact
end # of Svndump

#
# テストじゃなかったら実行する
#
if ( Pathname( __FILE__ ).realpath == Pathname( $0 ).realpath )
  tool = Svndump::Compact.new( )
  def tool.node_post_hook
    if (
         # ここの書き方で調整
        )
      @storable = true
    else
      @storable = false
    end
  end
  tool.run
end

cf.


2008-09-18

_ JSONの仕様にちょっと悩む

JSON

て、RFC に

RFC 4627 - The application/json Media Type for JavaScript Object Notation (JSON)

なってるし、YAML と違って結構いろんな言語でちゃんとサポートされてるので、シリアライズ形式として優れているなと思っています。*1

ただなんかちょっと腑に落ちないところがあって、上の RFC に以下のように書かれてるんですよね。

Any character may be escaped. If the character is in the Basic Multilingual Plane (U+0000 through U+FFFF), then it may be represented as a six-character sequence: a reverse solidus, followed by the lowercase letter u, followed by four hexadecimal digits that encode the character's code point. The hexadecimal letters A though F can be upper or lowercase. So, for example, a string containing only a single reverse solidus character may be represented as "\u005C".

2.5. Strings より。

で、

may ってどないやねん

*2

ただまぁ現実的には生で書くわけじゃないので、ライブラリの挙動が合ってればそれでよく、実際、

  • PHP
  • Ruby
  • JavaScript

  • PHP -> JavaScript
  • Ruby -> PHP
  • PHP -> Ruby

の3つではすべて日本語は \u 形式で表現され、それで問題なく解釈できるという動きになってます。

まぁ、そういうことなんでしょうねぇ。

Tags: JSON

*1 手で設定ファイルとして書くなら YAML の方が断然いいですけど。

*2 RFC 的にはちょっと弱めの should くらいの意味になるんでしたっけ?


2011-09-18

_ 日記ネタを掘り起こしている

本当はコードを書きたいんだけど、うまくアイディアが出てこないとか考えるのに使えるまとまった時間が足りないとか、なんか寝坊しちゃうとか昼寝しちゃうとか。

なんかそんな感じでダラダラしてる。まー休みなんだし、ダラダラすればいいのよ。勉強会に出たり git push しないといけないような強迫観念など不用なのよ。

疲れが取れてない気もするし、ちょっとよろしくない感じ。もっとダラダラ。ずっとダラダラ。

そう言えばものすごく久しぶりにSUBWAY食べた。店舗には石川県初進出って書いてあって、それはちょっと嘘書いちゃいかんよと思った。金沢は初めてだが松任にはあったぞ。

久しぶりすぎて思い出せないんだけど、バジルソースってなかったっけ。バジルマヨネーズだった。マヨネーズは好きじゃないのよね。

パンが柔らかくておいしかった。最近ああいうパンを出す店はあまりないのでとても好印象。金沢の人の新しもの好きが落ち着いたら贔屓にしようと思う。落ち着いたらなくなるかもしれんけど。

もう2, 3店舗くらい出してくれないかな。ちょっと不便。

Tags: 日々