すぱいだー日記。

2008.10.15(Wed)

Firefox 3.1 Beta 1 をインストールしたのはいいんだが・・・

  • 検索ボックスから検索してもなにも起こらない!
  • Highlight all が効かない!
  • FireGesture でタブを閉じるをするとタブが1枚の場合はブラウザ毎落ちちゃう!

上二つは厳しいなぁ・・・βといえど・・・αは問題なかったし。三つ目は仕様変更とかいう記事をどこかで見た気がするんだけど忘れた。でも、これは安易にタブを連続で消しまくれないので直したくてスクリプトを書いてみた。

f:id:spider-man:20081015212255j:image

FireGesture のオプションで登録

if(gBrowser.browsers.length != 1) {
  gBrowser.removeCurrentTab();
}
else {
  gBrowser.getBrowserAtIndex(0).loadURI("about:blank");
}

タブが複数あるときはカレントのタブを閉じて、無い時は about:blank を表示する単純なスクリプト

で、OKと思ったら甘かった。新規にページを開いた時に新しいタブ開いちゃう。残ったタブに読み込んでくれない orz

しかも right_click_close でタブ閉じた時も同様にブラウザ毎閉じられちゃうなぁ・・・これは嫌すぎる。

成功したので追記!

新しいタブで起動しちゃうのは、単純に load しちゃうと歴が残ったままになるのが原因じゃないかなぁと思って試してみたらできた!

if(gBrowser.browsers.length != 1) {
  gBrowser.removeCurrentTab();
}
else {
  gBrowser.getBrowserAtIndex(0).loadURIWithFlags(null, 128);
}

この 128 という値は

引数に指定した読み込みフラグ(flags) および与えられたリファラ(referrer)、文字セット(charset)、POST データURL を document に読み込みます。reloadWithFlags メソッドで許可されたフラグに加え、次のフラグも有効です。

* LOAD_FLAGS_IS_REFRESH: このフラグは、meta タグの refresh や redirect によって URL が読み込まれたときに使用されます。

* LOAD_FLAGS_IS_LINK: このフラグは、ユーザリンククリックして URL が読み込まれたときに使用されます。これに応じて HTTP Referer ヘッダが設定されます。

* LOAD_FLAGS_BYPASS_HISTORY: URLセッション履歴に追加しません。

* LOAD_FLAGS_REPLACE_HISTORY: セッション履歴内の現在URL を新しいものと置き換えます。このフラグリダイレクト使用されます。

loadURIWithFlags

この中の LOAD_FLAGS_REPLACE_HISTORY を使ったんだけど、値の取り方が分からなくてググったら 128 ってのがヒットしたのでそのまま使った(;´Д`)

right_click_close にも導入するかな。

やっぱ成功してなかったので追記

ページを開いてリンクで移動した後だと、最後の歴しか上書きされないっぽ・・・。単純に空タブを新規追加して、その後に開いてたタブを閉じるようにした。

if(gBrowser.browsers.length != 1) {
  gBrowser.removeCurrentTab();
}
else {
  var tab = gBrowser.getBrowserAtIndex(0);
  gBrowser.addTab(null);
  gBrowser.removeTab(tab);
}

今度こそ大丈夫っぽいが・・・。

2008.10.14(Tue)

今日学んだこと

コマンド説明今まで
gg1行目に移動:0
40G40行目に移動:40

viPlugin でも使えたし今から使いまくるぜ〜。

2008.10.13(Mon)

日経ソフトウエア 2008年 11月号

日経ソフトウエア 2008年 11月号 [雑誌]

日経ソフトウエア 2008年 11月号 [雑誌]

久々に購入。Java とか自分が知ってる領域を見るとそんな難しいこと書いてないよなぁと思うけど、C とか知らないところを読むと良く分からんなぁと思うところがあった。全般的に知ってる人にはどうって事無い記事が多いのかなぁという印象を受けたのだった。

ちょっとずつ C を勉強したいと思うんだけど、目的がこれと言って無いので進まず今に至る。

ActiveRecord っぽくしてみた

require 'active_axs'

ActiveAXS::Base.establish_connection(
  :source => "test.mdb" 
)
class User < ActiveAXS::Base ; end
class Job < ActiveAXS::Base ; end

puts User.find_first(:id => 1)[:name]
puts Job.find_first(:id => 1)[:name]

なかなか良い感じじゃね?(名前windows 限定以外は)

win32ole with ADO 経由でプライマリキーの取り方が分からん

field 名とカラムタイプの取り方は分かったんだけど、プライマリキーの取得方法が謎・・・

primary = connection.OpenSchema(28 , ["pubs", "dbo", table_name])

配列引数の pubs と dbo を何か設定すれば良さそうだけど不明。

require 'win32ole'
module RecordSet
  def [] field
    self.Fields.Item(field).Value
  end

  def []= field,value
    self.Fields.Item(field).Value = value
  end

  def each_record
    if self.EOF or self.BOF
      return 
    end
    self.MoveFirst
    until self.EOF or self.BOF
      yield self
      self.MoveNext
    end
  end
end

connection = WIN32OLE.new("ADODB.Connection")
connstr = "Driver={Microsoft Access Driver (*.mdb)};DBQ=test.mdb;"
connection.Open(connstr)

table_name = "Users"
# get fields
schemas = connection.OpenSchema(4 , [nil, nil, table_name])
schemas.extend RecordSet
schemas.each_record{|r|
  puts r["Column_Name"] + "-" + r["Data_Type"].to_s
}
# get primary keys
primary = connection.OpenSchema(28 , ["pubs", "dbo", table_name])
primary.extend RecordSet
primary.each_record{|r|
  puts r["Column_Name"]
}

3km

忘れるところだった。

今日体育の日の影響かかなりの人だった。大会はもちろん親子連れがかなりいた。

2008.10.12(Sun)

ActiveRecord から ODBC 接続

mdbtools がうまくいかないけど、ActiveRecordODBC Adapter を見つけたのでこれはいけると思い

activerecord-odbc-adapter (2.0)
odbc-rails (1.5)

2 つを gem からインストールしてもうまくいかなくて、

For accessing ODBC data sources from the Ruby language

ODBC Binding for Ruby

ここから 0.9994 のものをインストール。呼び出し側はこんな↓感じで、データソース名か、mdbファイル指定で直接取れたらいいなぁと思って書いてみた。

require 'rubygems'
require 'active_record'

ActiveRecord::Base.establish_connection(
  :adapter  => "odbc",
  :dsn => "test"
#  :conn_str => "Driver={Microsoft Access Driver (*.mdb)};DBQ=test.mdb;"
)

class User < ActiveRecord::Base
end

p User.find(:all)

結構時間かかったんだけどなぁ・・・結局

ODBCAdapter: Unsupported database (access)

だった orz

追記

/usr/lib/ruby/gems/1.8/gems/activerecord-odbc-adapter-2.0/lib/active_record/vendor

この辺りにあるファイルを真似て ODBCExt モジュール定義した上で odbc_adapter.rb にある dbmsNameToSym の変換定義を追加すればいいのかなぁ・・・と模索してみたけど orz

ActiveAXS

仕方がない(?)ので試しに win32ole 版のデータソースまたは mdb ファイルからデータを検索する ActiveAXS を作ってみた

ActiveRecord の define_attr_method と、るびまに載っていたソースを参考に以前から作ってたものを流用してやっつけ仕事をしてみた。

require 'win32ole'
module ActiveAXS
  class Base
    def self.set_source(source)
      define_attr_method :source , source
    end
    def self.set_table_name(table_name)
      define_attr_method :table_name , table_name
    end
    def self.set_user_id(user_id)
      define_attr_method :user_id , user_id
    end
    def self.set_password(password)
      define_attr_method :password , password
    end
    def self.find_first(keys)
      begin 
        connection = create_connection
        sql = create_search_sql(keys)
        rs = connection.Execute(sql)
        rs.extend RecordSet
        fields = rs.Fields
        list   = Array.new
        rs.each_record{|record|
          list.push(RecordMap.new(record , fields))
        }
        list.first
      ensure
        connection.Close if connection
      end
    end
    private
    def self.define_attr_method(name, value=nil, &block)
      sing = class << self; self; end
      sing.class_eval "def #{name}; #{value.to_s.inspect}; end" 
    end
    def self.create_connection
      connection = WIN32OLE.new("ADODB.Connection")
      connstr = ""
      if mdb_access?
        connstr << "Driver={Microsoft Access Driver (*.mdb)};"
        connstr << "DBQ=#{source};"
      else
        connstr << "DSN=#{source};User ID=#{user_id};Password=#{password};"
      end
      connection.Open(connstr)
      return connection
    end
    def self.mdb_access?
      return source =~ /.*\.mdb/
    end
    def self.create_search_sql(keys={})
      sql = "select * from #{table_name} "
      if !keys.empty?
        where = "where "
        keys.each{|key , value|

          key = key.to_s if key.kind_of? Symbol
          next if key == :orderby
          where << " and " if where != "where "

          if value.kind_of?(Integer)
            where << key + "=" + value.to_s + " "
          elsif value.match("%")
            where << key + " like '" + value + "' "
          else
            where << key + "='" + value + "' "
          end
        }
        sql << where

        if keys[:orderby]
          sql << "ORDER BY "
          for i in 0...keys[:orderby].length
            sql << "," if i != 0
            sql << keys[:orderby][i]
          end
        end
      end
      sql
    end
  end
end

module ActiveAXS
  class RecordMap
    def initialize(record , fields)
      @map = Hash.new
      for field in fields
        @map[field.Name] = record[field.Name]
      end
    end
    def [](key) 
      return @map[key]
    end
    def to_s
      puts @map.to_s
    end
  end
  module RecordSet
    def [] field
      self.Fields.Item(field).Value
    end

    def []= field,value
      self.Fields.Item(field).Value = value
    end

    def each_record
      if self.EOF or self.BOF
        return 
      end
      self.MoveFirst
      until self.EOF or self.BOF
        yield self
        self.MoveNext
      end
    end
  end
end

使う時

class User < ActiveAXS::Base
  set_source "test.mdb"
  set_table_name "User" 
end
class Job < ActiveAXS::Base
  set_source "test.mdb"
  set_table_name "Job" 
end

puts User.find_first(:id => 1)
puts Job.find_first(:id => 1)

とりあえずそれっぽく検索はできてるみたい。ActiveRecord継承して内部ロジックを流用できたらいいなぁと思いつつソースを追ってみるかなぁ。

2008.10.11(Sat)

マクロスF のオペレータ

3 人いるうちの1人がこなたで、1人がつかさだと言うことを今日知った。つかさの声に似てるなぁとは思ってたが。

それだけ。

activemdb が動作しない

linux からでも Microsoftmdb (Access) を操作できるライブラリ(検索に限る)。これを動かすには mdbtools が必要。最初はソースを持ってきて make したもののエラーがでるので困ってたが

sudo apt-get install mdbtools

で OK だった。続けて gem からインストール

sudo gem install activemdb

例えば test.mdb というファイル名で Users テーブルを用意する。

idnamedescription
1basyuramain user
2spider-mansub user

検索するソースを用意する。

require 'rubygems'
require 'active_mdb'

class User < ActiveMDB::Base
  set_mdb_file 'test.mdb'
  set_table_name 'Users'
end

user = User.find_first :id => 1
puts user.name
puts user.description

いやぁ、簡単だねー♪と思ったらここからレコードが取れない謎のハマリ。いろいろ試してみて分かったのは、where 句指定があると mdbtools が取ってきてくれないこと。インタラクティブモードで検証してみた。

$ mdb-sql -Fp -d :: test.mdb
1 => select * from Users
2 => go

name::description::id
basyura::main user::1
spider-man::sub user::2

登録してある 2 レコードが取れる。

1 => select * from Users where id = 1
2 => go

name::description::id

取れない orz

mdb を直接開いて同じ sql を投げたら OK なので mdbtools 側の問題だと思うんだけど、、、または office 2003 がサポート外とか?

2008.10.10(Fri)

DocDiff

テキスト比較ツール。

DocDiff compares two text files and shows the difference. It can compare files word by word, char by char, or line by line. It has several output formats such as HTML, tty, Manued, or user-defined markup.

DocDiff

例えば、0.txt と 1.txt があったとして

  • 0.txt
a b c d
a e f g
a h i j
  • 1.txt
a b c d
a e h g
a h i j

これを docdiff すると

$ docdiff --tty 0.txt 1.txt

f:id:spider-man:20081011003721j:image

という具合に色つきでコンソールに出力される。html 出力も可。

andlinux だと sudo apt-get install docdiff で入れられるんだけど、cygwin は手動でインストールしないといけない。インストールといってもコピるだけ。

仕事データ更新した後に前後データを比較して間違った更新がされていないかをチェックしないといけなくなった。access でテーブル開いて、キーで絞って、比較して・・・なんてやってられるかーヽ(`Д´)ノ

てことで、ruby から win32ole を使ってデータソース経由で検索して結果をテキストに出力。ついでに更新前後を docdiff で比較してサッと確認するようにした。

ホントはテストケース書いて再利用したいんだけど、世の中テストケースが書けなくなったプログラムなんていくらでもあるんです・・・。最初からテスト書く気でコーディングしないとダメ。後からやろうなんてのは絶対無理。思った時には手遅ればっかりなのだ。

andlinux いいじゃんと思ってたけど、メモリ使うのと微妙時間がずれるのと、メインマシンwindows なので win32 api 叩けないのが不便とか、なんだかんだで cygwin の方がやっぱ便利だなぁと思い直しつつあるが linux 環境も捨てがたい。

2008.10.09(Thu)

Error.number

JScript なんだが、

エラー番号は 32 ビット値です。上位の 16 ビット ワードは機能識別符号です。下位のワードは実際のエラー コードです。実際のエラー コードを読み取るには、& (ビットごとの And) 演算子使用して、number プロパティと 16 進数の 0xFFFF を組み合わせます。

number プロパティ

知らなかった。エラー出ても行数ぐらいしか役に立たなかったのであまり気にしたことなかった。

try {
    var v = 5;
    v.indexOf("a");
} catch(e) {
   alert(e.number & 0xFFFF); //=> 438
}

この値の一覧はどこにあるんだろうか・・・。

付箋を貼る

「naoya 氏の本が付箋だらけ」エントリを読んで自分も導入してみた。

勉強していて本の気になるところに付箋を貼り、問題集で解けなかったら緑の付箋、2回目に解けなかったらピンクの付箋を貼るとなどしてみると、これが良い感じ。あとで読み返したりチェックする時に便利。

なにより、達成感を味わえる。

小説を読む時も心に残ったところに貼ってみたり、後で感想を書く時にポイントになる場所に貼ってみたり。

なかなかいいよ付箋ライフ。問題は常に付箋を持ち歩いているわけじゃない(忘れる)ところかなぁ。