Mountain Lion で Audirvana 1.0 を起動できるようにする

音が気に入ってずっと使っていたミュージックプレーヤー Audirvanaですが、何となく1.0にバージョンアップしたら起動しなくなってしまいました。

原因

使用していたライブラリが、同梱されなくなったから。の様子。
https://code.google.com/p/audirvana/issues/detail?id=89

対応 1

/usr/lib に、 上記ページに添付(最下部)されている libltdl.7.dylib を コピー or Link 。
私のマシン(10.8.3)では、これでうまく起動しました。

対応 2

Audirvana のバージョンを 0.9.5 に落とせば、動きます。
こちらも、私のマシンで起動確認できました。

対応 3

有料の Audirvana Plus を買う。 $74 (2013-04-08 現在)
こちらは、残念ながら、買っていないので未検証。

iPhone5 の Kindle app で amazon.com 時代の Kindle本が表示されない。

今日、iPhone5 から Kindle app を起動して、今まで使っていたものと同じアカウントを登録したら、「クラウド中に本がありません。」
グーグル先生したところ、以下の記事に行き当たり、amazon.comからその通りにやってみてもエラーでした。(記事の人もエラーになっちゃったようです)

米Amazonから買った国際版Kindle端末や電子書籍はどうなるのか | 日経 xTECH(クロステック)

こんな様子です。

Country Settings から Learn More

1つのライブラリであるかのように、統合されるよ!とのこと。「Yes」

「なんか出来なかったので、カスタマーサービスにご連絡ください」

試しに amazon.co.jp から同様の手順をやってみる

それっぽい画面が...住所を登録して、「詳しくはこちら」へ。


カスタマーサービスにご連絡ください」とのこと。えぇー。


そのリンクから、以下のように設定して「Eメールで問い合わせ」中。さて。


んーでもヘルプを見ると結合しない方がいいのかな...よくわかんないな。
Amazon.co.jp ヘルプ: Amazon.comにアカウントをお持ちのお客様

eclipse 3.7 で Failed to create The Java Virtual Machine ※VM設定を書く場所に要注意


環境は、


こちらのかた
[開発環境]Eclipse起動時に"Failed to create the Java Virtual Machine."メッセージが表示されて起動できない時の対処法 | あんどろーなつ
や、こちらのかた
http://www.cozzbox.com/wordpress/archives/806
と同じ現象です。


ダウンロードしてそのままの eclipseeclipse.exe より起動したら

Failed to create The Java Virtual Machine

でした。

対応

あんどろーなつさんの

○対処法その1
"-Xmx512m"を"-Xmx256m"に変更する。
ちなみに、Galileo(Version 3.5)では最初から"-Xmx256m"となっている。

○対処法その2
"-vmargs"の前に

(javaw.exeのパス)

という2行を追加する。
ちなみに、Galileo(Version 3.5)ではこの記述はない。

で、起動できるようになりました。
注意すべきは、 "-vmargs"の前にということです。
設定ファイルの最後に書いても効かないので、要注意。

cygwin で MySQLのコンソール

gnupack の cygwin で、どうしても MySQLのコンソールが使いたくて、ソースからビルドしたらエラーになりました。


バージョンは以下の通り

gnupack 7.02
MySQL 5.1.60


エラーは次の通り

readline/readline.h:79:29: fatal error: sys/ttydefaults.h: No such file or directory


「sys/ttydefaults.h: No such file or directory」で google さんに検索依頼。以下のサイトがひっかかりました。


曰く
「readline は cygwin で別個に入れて、 configure では --without-readline しなさい」
「configure 実行済だったら、 ディレクトリを clean up しておきなさい」


つまり、

make distclean
./configure --without-readline CFLAGS=-O2
make 
make install


ちなみに、 Windowsに install した ローカルの MySQL に入るには

mysql -uroot -p -h 127.0.0.1

localhost ではダメなようです。


蛇足になりますが、http://bugs.mysql.com/bug.php?id=45057 を見ると...

[25 May 2009 12:16] Miguel Solorzano
Thank you for the bug report. Sorry but currently the Cygwin isn't supported.

Oh...orz

Ubuntu11.10 と emacs23 と UTF-8-MAC

今年はじめから、Macユーザになりました。
で、Macemacs で保存したテキストファイルを、Ubuntu(11.10) の emacs で開くと、濁点まわりが大変残念な感じになっていました。


原因は、Mac 側の設定ミス。
どうやらこれは、「UTF-8-MAC問題」というのに巻き込まれたらしい。


どこかのサイトを参考に、以下の4行を入れていたのですが、

(require 'ucs-normalize)
(prefer-coding-system 'utf-8-hfs)
(setq file-name-coding-system 'utf-8-hfs)
(setq local-coding-system 'utf-8-hfs)

prefer-coding-system に hfs は付けない方がいいっぽい。(Mac以外も考慮するなら)


以下へ修正。

(require 'ucs-normalize)
(prefer-coding-system 'utf-8)
(setq file-name-coding-system 'utf-8-hfs)
(setq local-coding-system 'utf-8-hfs)


既存のファイルを、iconvやコピペで地道に変換。(Mac側で)
iconv が何だか失敗することがあったので、すんなりいかず。
gedit 等、他のエディタでは普通に表示できていたので、納得もいかず。(開く側の emacs で何とかできなかったものか)


iconvはこんな。

iconv -f UTF-8-MAC -t UTF-8 org_file > new_file


ついでに、フォントを Ricty
参考


できあがり。

Thrive on Development #1

Thrive on Development という勉強会に参加してきました。

http://kokucheese.com/event/index/1308/

ことの発端は、TDD Boot Camp に興奮した私が先輩技術者に教えを請うているうちに勉強会になってしまったというもの。
ありがたいことです。
そんな経緯もあって、TDD について15分ほど話させていただきました。

TDDのやり方よりは、TDDを学ぶことで得られる日々の変化について。

実感として、あまりコードを書かない立場に居たとしても、TDDを学ぶことに意味はあると思います。

  • まずREDを見るということ
  • 不安をテストにするということ
  • 自分が最初のユーザになるということ
  • テストは味方であるということ

非常に充実した一日でした。ご参加いただいた皆様、ありがとうございました。

もう一回これを写経したくなってきたなぁ。

テスト駆動開発入門

テスト駆動開発入門

"TDD" Boot Camp 参加。と、宿題をやった。

2009-12-19。「これは伝説のイベント」と各所で評判のTDDBCに参加してきました。TDD本を読んだりxUnitの読書会に参加したりしていますが、なかなかリズムというものは体験できるものではありません。そして何より、30組以上がいっせいにペアプロやるってすごいです。


スタッフ・運営の皆様、スポンサーの皆様、かつてないすばらしいイベントをありがとうございました。


当日どんな様子だったかは、Lasseさんの写真を見ていただくとよいかと思います。
動画も...!

ペアプロの感想

実は、というか何というか、当日までペアプロにちょっとびびっていました。
日常のお仕事でそれほどプログラムを書く訳ではないので、自分の実力に不安があったりもしました。
しかし、です。体験してみて、これは楽しいものだということがとても良くわかりました。実力や経験を越えて、あれこれしゃべりながらプログラムする楽しさを味わえます。もちろん、とても勉強になります。すごく勉強になります。テストを書く前に実装に手を出してしまった時、温かく(人によっては)叱ってくれます。自分のコードに対する性癖も丸わかりです。

  • 前半でペアさせていただいたid:a-hisameさん(「あ”、今1つバグに気づいた」のバグが気になるところ。同じキーでputとかその辺かな?)
  • 後半でペアさせていただいたid:hikki-515さん
  • 反省会でペアさせていただいたmitimさん

ありがとうございました。ペア中、変なこと言ってたらごめんなさい。


ちょっと主旨からは外れてしまうかもしれないのですが、自分の選んだ言語以外のコードを見るのも楽しかったです。休み時間に、全言語のテーブルを回らせてもらいました。

TDDの感想

仕様と不安をテストにする大事さ、くるくる回す軽快さ、気持ちよさを実感することができました。

  • テストを先に書くことで脇道にそれない。グリーンへ集中。
  • リファクタをテストが守ってくれる。冒険も可能。
  • 不安の顕在化。テストで解消。健康なコードへ。


どうも自分は心配性らしく、ペアプロ中にテストを実行し過ぎなのかも?
TDD実践者の回しっぷり(言ってしまえば、もがく様)を見ることができると、より良かったなと思います。

持ち帰って、宿題

イベントの数日後、反省を兼ねてmitimさんと復習ペアプロをさせていただきました(仕様変更の2まで)。
Ruby、初Rspec、初gitです。さらしてしまいます(mitimさん、良いですよね???)。


イベント当日は、「ハッシュ」・「キーの配列」・「登録時間の配列」の3つをフィールドに持つ実装が多かったので、別の方向でやってみました。正直、遅いです。(一応、メモリ効率重視ということで)。

lru_cache_spec.rb

# -*- coding: utf-8 -*-
require 'lru_cache'

describe LruCache do
  describe "初期化に関するテスト" do
    it "サイズを渡したらそのサイズのキャッシュができること" do
      targ = LruCache.new(10)
      targ.limit.should == 10
    end

    it "サイズにマイナス値を渡した場合、例外が発生すること" do
      lambda{ LruCache.new(-1) }.should raise_error(ArgumentError)
    end

    it "サイズにnilを渡した場合、例外が発生すること" do
      lambda{ LruCache.new(nil) }.should raise_error(ArgumentError)
    end

    it "サイズに数値以外を渡した場合、例外が発生すること" do
      lambda{ LruCache.new("a") }.should raise_error(ArgumentError)
    end
  end

  describe "値の出し入れに関するテスト" do
    before :each do
      @targ = LruCache.new(3)
    end
    
    it "入れたものが同じキーで取りだせること" do
      @targ.put("a", "A")
      @targ.get("a").should == "A"
      @targ.put("b", "B")
      @targ.get("b").should == "B"
    end

    it "キャッシュの中にないキーを取り出すとnilが返ること" do
      fill(@targ, "a", "b", "c")
      @targ.get("d").should be_nil
    end

    it "キャッシュがサイズを越えない場合、キャッシュの中で最も古いキーが取得できること" do
      fill(@targ, "a", "b", "c")
      @targ.eldest_key.should == "a"
    end

    it "キャッシュが空の場合、最も古いキーとしてnilが返ること" do
      @targ.eldest_key.should be_nil
    end

    it "キャッシュがサイズを越えた場合、越えた分の値が消えていること" do
      fill(@targ, "a", "b", "c", "d")
      @targ.get("a").should be_nil
      @targ.eldest_key.should == "b"
    end

    it "現在キャッシュされている値の個数が取得できること" do
      @targ.size.should == 0
      fill(@targ, "a", "b")
      @targ.size.should == 2
    end
    
    it "同じキーを渡した場合、上書きされること" do
      fill(@targ, "a", "b")
      @targ.size.should == 2
      @targ.put("a", "x")
      @targ.size.should == 2
      @targ.get("a").should == "x"
    end

    it "最も古いキーをgetすると次に古いキーが最も古いキーとして取得できること" do
      fill(@targ, "a", "b", "c")
      @targ.eldest_key.should == "a"
      @targ.get("a")
      @targ.eldest_key.should == "b"
    end
  end

  describe "キャッシュサイズ変更に関するテスト" do
    before :each do
      @targ = LruCache.new(3)
      fill(@targ, "a", "b", "c")
    end

    it "新しいキャッシュサイズにマイナス値を渡した場合、例外が発生すること" do
      lambda{ @targ.resize(-1) }.should raise_error(ArgumentError)
    end

    it "新しいキャッシュサイズにnilを渡した場合、例外が発生すること" do
      lambda{ @targ.resize(nil) }.should raise_error(ArgumentError)
    end

    it "新しいキャッシュサイズに数値以外を渡した場合、例外が発生すること" do
      lambda{ @targ.resize("a") }.should raise_error(ArgumentError)
    end

    it "キャッシュサイズが変更できること" do
      @targ.limit.should == 3
      @targ.resize(100)
      @targ.limit.should == 100
    end

    it "キャッシュサイズを増やした場合、キャッシュの内容が変わらないこと" do
      @targ.resize(4)
      @targ.size.should == 3
      should_have(@targ, "a", "b", "c")
    end

    it "キャッシュサイズを減らした場合、リミットを越えたキャッシュが消えること" do
      @targ.resize(2)
      @targ.size.should == 2
      should_not_have(@targ, "a")
      should_have(@targ, "b", "c")
    end

    it "キャッシュが空の場合に、キャッシュサイズを変更してもエラーが起こらないこと" do
      @targ = LruCache.new(3)
      lambda{ @targ.resize(1); @targ.resize(1000); }.should_not raise_error
    end
  end
  
  describe "キャッシュの保持期間に関するテスト" do
    before :each do
      # 保存期間に10秒を設定する
      @targ = LruCache.new(4, 10)
      @filled_time = now
      fill(@targ, "a", "b", "c")
    end

    it "キャッシュが登録された時間が取得できること" do
      @targ.birthtime_of("a").should == @filled_time
    end

    it "保持期間を過ぎたキャッシュが消えること" do
      should_have(@targ, "a")
      set_forward(9)
      should_have(@targ, "a")
      set_forward(1)
      should_not_have(@targ, "a")
    end

    it "保持期間を過ぎていないキャッシュが消えないこと" do
      set_forward(9)
      @targ.put("d", "D")
      set_forward(1)
      should_not_have(@targ, "a", "b", "c")
      should_have(@targ, "d")
      set_forward(9)
      should_not_have(@targ, "d")
    end
  end
end

def fill(targ, *keys)
  keys.each do |v|
    targ.put(v, v)
  end
end

def should_have(targ, *keys)
  keys.each do |v|
    targ.get(v).should_not be_nil
  end
end

def should_not_have(targ, *keys)
  keys.each do |v|
    targ.get(v).should be_nil
  end
end

def now
  set_forward(0)
end

def set_forward(second)
  time = Time.now + second
  Time.stub!(:now).and_return(time)
  return time
end

lru_cache.rb

class LruCache
  attr_reader :limit

  def initialize(size, lifespan = 10)
    raise ArgumentError.new unless valid_size?(size)
    @limit = size
    @cache = []
    @lifespan = lifespan
  end

  def put(key, value)
    remove_cache(key) if pick_out(key) != nil
    @cache << CacheValue.new(key, value)
    if @cache.size > @limit then
      @cache.shift
    end
  end

  def get(key)
    ret = pick_out(key)
    return ret == nil ? nil : ret.value
  end

  def size
    return @cache.size
  end

  def resize(size)
    raise ArgumentError.new unless valid_size?(size)
    (@limit - size).times do
      @cache.shift
    end
    @limit = size
  end

  def valid_size?(size)
    return size != nil && size > 0
  end
  
  def eldest_key
    return nil if @cache.size <= 0
    return @cache[0].key
  end

  def birthtime_of(key)
    ret = pick_out(key)
    return ret == nil ? nil : ret.birthtime
  end

  private

  def pick_out(key)
    remove_dead_caches
    @cache.each do |v|
      if v.key == key then
        rotate(v)
        return v
      end
    end
    return nil
  end
  
  def rotate(value)
    remove_cache(value.key)
    @cache << value
  end

  def remove_cache(key)
    @cache.each do |v|
      @cache.delete(v) if v.key == key
    end
  end

  def remove_dead_caches
    @cache.each do |v|
      lifetime = Time.now - v.birthtime
      remove_cache(v.key) if lifetime >= @lifespan
    end
  end
end

class CacheValue
  attr_reader :key, :value, :birthtime
  
  def initialize(key, value)
    @key = key
    @value = value
    @birthtime = Time.now
  end
end

githubにも上げてみました。初githubhttp://github.com/htada/tddbc-lrucache/