フェルマータ

個人用のメモ。ソフトウェアの導入とかが多くなる予定。

UTAU 音源を読み込む Go のコードを書いてみた

ポエム

本当に今さらなのだけれど Go を触ることになりそうなので手馴れている処理を Go で書いてみることにした。本職 Web エンジニアの割にえらいネイティブアプリ寄りなんだよなと思いつつも UTAU 音源読むところがちょうどよさそうなので実装してみた。

レポジトリ

github.com

超久々に個人レポジトリを更新した。 4 年くらい趣味プロしていなかったのか、フェルマータにしても休みすぎでしょう。

やったこと

shurabap.hatenablog.jp

これも 6 年前か。とりあえずこの辺のデータ構造をコードに起こした。

あんまりはまらなかったけれど、 function を mock できなさそうな雰囲気を感じたので、 interface に書き直すことにはなった。自前で mock を書けばいいんだろうけど、さすがに何回どんな引数で呼ばれたかを自分で書くのは苦しい。最初はこんな感じで書いていた。

// CharacterReader reads Character from filesystem.
type CharacterReader interface {
    Read(string) (*Character, error)
}

// CharacterReaderDefault is a default CharacterReader.
type characterReaderDefault struct {
    fileRead func(string) (string, error)
    characterFactory func(string) (*Character, error)
}

// NewCharacterReader creates a default CharacterReader that reads Character from filesystem.
func NewCharacterReader() CharacterReader {
    return characterReaderDefault{
        fileRead : fileRead,
        characterFactory : NewCharacter,
    }
}

CharacterReader の実装クラスは character.txt を読むことになるのでファイル読み込みをする関数を DI できるようにし、また Character のファクトリも DI できるようにしておいた。単体テストのためで、後々モック化しようと思ったが良い方法が見つからず、結局 testify を導入して interface を注入するように変えた。

// CharacterReader reads Character from filesystem.
type CharacterReader interface {
    Read(string) (*Character, error)
}

// CharacterReaderDefault is a default CharacterReader.
type characterReaderDefault struct {
    fileRead fileReader
    characterFactory characterFactory
}

// NewCharacterReader creates a default CharacterReader that reads Character from filesystem.
func NewCharacterReader() CharacterReader {
    return characterReaderDefault{
        fileRead: fileReaderDefault{},
        characterFactory: characterFactoryDefault{},
    }
}

これで良し。とりあえず一通り触ることを優先したのでテストコードまで書いたけど動作検証はしていない。もともと BASIC -> C -> C++ -> C++ with Qt と来ているので文法は慣れれば気にならなかった。

参考

github.com