だいきちメモリアル

ブログです

SwiftPackageManagerを使うための覚書

以前SwiftPackageManagerを利用してライブラリを作成したことがあったが、使い方をすっかり忘れてしまったため覚書として使い方のメモを残しておくことにする。

プロジェクトディレクトリの作成

SwiftPackageMamagerにはプロジェクトディレクトリを作成してくれる機能は無いため自前でプロジェクトディレクトリを作成しておく必要がある。

ディレクトリを作成したら、そのディレクトリに移動してSwiftPackageManagerの初期化を行っていくことになる。

mkdir /path/to/Project
cd /path/to/Project

初期化

swift package init --type [empty|library|executable|system-module]というコマンドを実行することでプロジェクトのスケルトンを生成することができる。

--typeに指定したオプションによって生成されるスケルトンが異なってくる。
生成内容はそれぞれ下記の通り。

オプション 生成物
empty 空のプロジェクトスケルトンが生成される、用途的に使うことはほぼ無いのではないか?
library 他のSwiftプロジェクトから利用可能なライブラリを生成するためのスケルトンが生成される。
executable 実行可能なコマンドのためのスケルトンが生成される。
system-module システムモジュールを生成するためのスケルトンが生成される。

SwiftPackageManagerでビルドを行うには特定のプロジェクト内構造を持つ必要がある。
この構造を自分で考えるコストが必要になるemptyオプションは基本的に利用するケースが無いように思われる。

Xcodeプロジェクトの生成

swift package initでプロジェクトの初期化を行うと開発が行えるようになる。
通常、Swiftの開発にはXcodeを利用するため*1Xcodeのプロジェクトファイルを生成する必要がある。

Xcodeプロジェクトの生成は下記のコマンドを実行すれば良い。

swift package generate-xcodeproj

コマンドを実行すると、[ProjectDirName].xcodeprojという設定が生成されるので、これをXcodeから開けばXcodeを利用して開発を行うことができる。


以前使ったときはテストコマンドやビルドコマンドもあったような記憶があるのだが、どうも無くなってしまっているようだ*2
ブログに書いたことで次に利用する時はすんなり使えるようになっているとよい。

*1:AppCodeを利用するケースも一定数あるが、AppCodeのプロジェクト設定はXcode互換のため区別する必要は無いだろう。

*2:無くなったのが私の記憶なのかSwiftPackageManagerの機能なのか定かではないが…

オクトパストラベラー感想

ちょっと前に話題になっていたオクトパストラベラーというゲームをクリアした。

www.jp.square-enix.com

以下感想です。

シナリオ

  • 各キャラクター4章構成だが、4章の間にキャラクターの心情が変化していく様を描くのには無理があるキャラクターがちらほら(特にテリオン)
  • ゲーム上仕方がないのかもしれないがただの商人の娘であるトレサが強い謎
  • サイラス編がキャラクターの天然ぶりと相反してシナリオが怖い(4章を夜に暗い部屋でやると特に怖い)
  • ハンイット編はシナリオ的にはわりとよく出来ている、隠しボスへの布石みたいなものもあって気が付く人にとってはいいシナリオだと思う

戦闘

  • ブースト、ステータスアップ・ダウンを駆使して戦うことを覚えるとボス戦が楽になる
  • 上記を除くとごくごく普通のRPGな戦闘スタイル

フィールド

  • グラフィックが綺麗なのだが画面の輝度や周囲の明るさによってフィールドが見にくくなることがあった
  • ダンジョンの作りが単調なので、RPGとは入り組んだダンジョン!という人には物足りないかも(私は難しく考える必要がなかったので特に気にならなかった)
  • 宝箱に入っているものが多くの場合重要ではないので後半は宝箱を見つけてもスルーするようになっていた

フィールドコマンド

  • 盗むや買い取るはゲームが難しい人用の救済手段みたいなもののように感じた
  • 巷で噂されるほど感心はしなかったものの、新しい街に移動したあと盗むコマンドでレア装備を見つけるのが一つの楽しみになったのは間違いない
  • プリムロゼの誘惑で男性NPCキャラが「げへへ」という言葉を発するあたりに人間の業を感じずにはいられない

隠しボス

  • 最後の最後で8人全員必要とか辞めて!

感想はこんなところ。

正統派RPGを名乗るには*1ダンジョンの構造が少し残念だったように思うが、それを除けばなかなか良い出来のRPGだと思う。
気がついたら総プレイ時間が70時間程度になっていたので私としては楽しめたゲームだった。

*1:ソースは?

日本人の性質とプログラマー文化

異文化理解力という本を読んだ。

異文化理解力――相手と自分の真意がわかる ビジネスパーソン必須の教養

異文化理解力――相手と自分の真意がわかる ビジネスパーソン必須の教養

グローバルな人を相手にして働くビジネスパーソンが各国の文化的背景等から生まれるコミュニケーションの差異を明らかにし、どのように対処していくかという内容の本だ。

なお、「日本人の性質とプログラマー文化」と題しているがこのエントリはただの読書感想文であり、壮大な考察が述べられるものではない。


さて、ITエンジニアとして仕事をしていると他の職種と比べてITエンジニア特有の文化のようなものが形成されていおり、また、この文化が日本人の性質とされているものから外れている節があるように感じる。

例えば、無駄なミーティングを好まないだとか、情報をオープンにするだとか、ひどいコードを目の前にしたときに「なんだ、このクソコードは!」など堂々と暴言を吐く、などなど…

これらは仕事を効率よく進めることい対して非常に有用だが日本人の性質と照らし合わせると、ズレが生じておりITエンジニアの精神的な観点をすり減らしてしまうという問題はなかろうか?
特に、ITエンジニアはプログラムのソースコードを指して暴言を吐きがちだが、このオープンなフィードバックは明らかにITエンジニア諸氏の精神をすり減らしている場面をよくよく目にする。

これは一例に過ぎないが、私達はもう少し、ITエンジニアとしてではなく、日本人という文化に所属する人間を相手にして仕事をしているということに意識を向けたほうが良いのかもしれないと考えさせられた。


実はITエンジニアに留まらずIT企業というのが特殊な文化を構築しており、このあたりがまた従業員のモチベーションに関するミスマッチを起こしているというケースも目にすることがある。

エンジニアリングにせよ、IT企業にせよまだまだ若い産業であるので、これまでの文化とは異なる形態をとるのはおかしな話ではないが、その文化の所属する前に私達の考え方は自分の国の文化的背景がベースとして存在している。

これらを上手く迎合できるような振る舞いというのを考えていければと思った。

退職しました

これはITエンジニアの界隈で非常に流行している退職エントリというものだ。

ITエンジニアの界隈では人材の流動性が高いらしく*1、また、自身の情報を発信することが人材的価値の向上に繋がるケースモデルが一定数観測されることから、このような退職エントリが上がることは珍しいことではない。

私はITエンジニアとして業界に身をおいているのだが、この流行というものに倣って退職エントリというものを書いてみるに至った次第だ。*2


さて、先日8月末日をもって約3年と半年ほど所属した会社を退職した。

会社への不満、未来への成長の展望、これまでの感謝等、感情としては諸々が混じり合っているためどれがどうっだったという明確な理由を上げてもそれは違うことのように思われる。
故に、退職理由は簡単に書き記せるような明確なものではなく、様々な要素が重なった中である日「退職しよう」という判断が自分の中で下されたのだ。


いざ書いてみたが書きたいことが殆どないことに若干の寂しさを憶える。

なお、次に所属する会社はすでに決まっているためこのエントリに転職活動を示唆するものは含まれていない。

*1:ソースは?

*2:前置きを長く書いたが、単純に書いてみたかっただけ

Swiftで利用できるLooseCodableというライブラリを作った

LooseCodableというライブラリを作った。
CarthageとSwiftPackageManagerからインストールして利用することができる。

github.com

このライブラリを作ろうと思った動機だが、サーバーサイドのAPIレスポンスが安定していないというのが理由だ。

主にIntegerとString、IntegerとBooleanの型が様々な形式で返ってくるのだが、SwiftのCodable*1はこれらの型を曖昧に変換することを許さず例外を投げてくる。

例えば、Booleanで扱いたいケースで01で返ってくるケースとtruefalseで返ってくるケースが混在しているだとか、10で返ってくるか"10"で返ってくるかが混在しているかなど…

Codable登場以前は自前で書いたマッパーがこのあたりの差異をいい感じに吸収してくれていたのだが、Codableへ移行したと同時にこのような問題が顕在化してしまった。

Codableを利用すること自体は間違いのない選択だと考えているが、この気まぐれなAPIとは相性が悪い。
そこで、この気まぐれAPIを快く受け入れるべくLooseCodableを作ったというわけだ。


さて、このライブラリだが期待する型をLooseCodableという型で包んであげることでいい感じに差異を吸収してくれるものだ。

struct Hito: Codable {
    // このように定義しておくと
    let age: LooseCodable<Int>
}

// こんなデータが
let json = """
{
    "age": "10"
}
"""

// デコードできちゃいます!
let hito = try! JSONDecoder().decode(Hito.self, from: json.data(using: .utf8)!)
print(hito.age.value) // 10

上記のコードだとLooseCodableという型が表面に出てしまい、結果の値を得るためにvalueというプロパティを呼ぶのは、呼び出し側に多くの変更の負担が寄る可能性がありいただけない。
そもそもLooseCodableはCodableオブジェクトの外に見えている必要は無い。

このため定義するとき、LooseCodableを指定する型はプライベートにしておき、公開するプロパティをComputedにしたほうが良いだろう。

struct Hito {
    // LooseCodableなプロパティは非公開にし、
    private let _age: LooseCodable<Int>

    // 利用される値をComputedな公開プロパティにする
    var age: Int {
        return self._age.value
    }

    // JSONとプロパティのキーマッピングを忘れずに
    enum CodingKeys: String, CodingKey {
        case _age = "age"
    }
}

今回、初めてSwiftPackageManagerを利用してライブラリを公開してみたが、何もしなくてもCarthageでのインストールにも対応できていて中々に便利な代物だなと思えた。

ファイル構造を強制するなどとっつき憎い点もあったが、今後のSwiftにおけるライブラリ開発はSwiftPackageManagerで作成することを念頭に置いておきたいところだ。

*1:JSONデータをオブジェクトにマッピング等をしてくれる標準ライブラリ

公式Perlチュートリアル

先日のブログに書いたとおりPerl公式のチュートリアルを学んでいる。

daikichi.hatenadiary.com

最近WEBフロントエンドのライブラリのチュートリアルをこなすことが多いだが、 これらのチュートリアルは懇切丁寧に記されておりPerlチュートリアルに対しても同じようなものを想定していた。

しかし、内容は最低限Perlの基礎とかコンピュータ・サイエンスの基礎などの知識が必要とされる内容だった。 先にPerlの基礎を学んでいたおかげで特に問題無く読み進めらることができたが、
このチュートリアルは私のチュートリアルに対する概念は大きく崩すことになる内容だ。

さて、このチュートリアルだがちょっとしたジョークを交えた文章で書かれており読んでいると以外に楽しめる内容になっている。 内容もPerlの細かな挙動について触れられており、こういったところに新たな発見・気付きを得られるのは学ぶ上での喜びだろう。

ここから下はチュートリアルで学んだことの覚書を記していく*1

変数の定義

変数の先頭にプレフィクスをつけることで、データのタイプを分類出来る

# スカラーは`$`
$shin_gi = true;
$number = 42;
$string = "moji moji";

# 配列は`@`
@array = ( 1, 2, 3, 4, 5 );

# ハッシュは`%`
%hash = ( "ha" => "shun!!" );
%hash = ( "ali", "as" ); # こう書いてもいいが、分かり難いので多分書かない

尚、配列やハッシュに格納出来るのはスカラー値だけなのでネストするデータ構造などが扱えない。
これを解決するために参照というスカラー値を作って格納するらしい。

# 参照を作るには、配列やハッシュの先頭に`\`をつける
$aref = \@array;
$href = \%hash;

# 無名配列・無名ハッシュへの参照を持てる
# オリジンを壊されないという意味でこっちのほうが使いやすそうだが…
# (メモリ使用量などが問題になるか?)
$aref = [ 1, 2, 3, 4, 5 ];
$href = { "no" => "name" };

# 参照へアクセスしたいときは`{}`でくくることでアクセスできるようになる
@{$aref}       # => @array
${$aref}[0]    # => $array[0]
%{$href}       # => %hash
${$href}{"no"} # => $hash{"no"}

# 参照先の要素アクセスにはエイリアスが存在する(こちらを使ったほうが読みやすくて良い)
$aref->[0]    # ${$aref}[0]
$href->{"no"} # ${$href}{"no"}

正規表現

Perlは文字列操作が凄いというだけあってかなりボリュームが高い内容となっていた。
なので基本的な部分にのみ目を通して読み飛ばした。

以下は基本的な部分の覚書である。

# `=~`演算子でマッチの真偽をチェックできる
if ($value =~ /kihonn/) {
    print "matched!";
}

# `!~`演算子でアンマッチの真偽をチェックできる
if ($value !~ /unmatch/) {
    print "unmatched...";
}

# 正規表現のデリミタは`m`オプションを指定することで変更ができる
"Henkou dekiru!" =~ m{dekiru!};

# グループ化して取り出す
if ("grouping!!" =~ /(ping).*(!!)$/) {
    print $1; # "ping"
    print $2; # "!!"
}

# マッチした値はリストで返るのでこういうふうに書ける
($ping, $bikkuri) = ("grouping!!" =~ /(ping).*(!!)$/);

スレッド

Perlではスレッドを利用することができるらしい。
Perlのスレッドはスレッドセーフらしいので、スレッドを生成した時点でデータがスレッド内にコピーされる。
(配列やハッシュの参照を渡してみたところ、参照すらも(参照先にある実態も)コピーされました)

※スレッドセーフなのは、スレッド生成時にすべてのデータをコピーするから。 データ以外(chdirなどでプロセスレベルで影響を与えるもの)はすべてのスレッドに影響を及ぼしてしまう。

use threads;

# サブルーチンの参照を渡すと、その処理をスレッド内で行ってくれる。
my $thread = threads->create(sub { print "Hello world!!"; })

# `join`メソッドを呼び出すと、スレッドの完了を待機、戻り値がある場合は取得、スレッドの後始末を行ってくれる。
# スレッドの後始末をしないコードはエラーになる。
$thread->join();

# `detach`メソッドはスレッドの後始末を行うだけ。
# スレッドが実行中であっても処理結果が出力される前に`detach`を呼び出せばその結果を得ることは出来ない。
$thread->detach();

上記はスレッドの基本的な利用方法でデータのシェア、キューの存在やセマフォ等も存在しますが、
これらが必要になるケースは稀だろうということで軽く読み進めるだけに留めておいた。*2

オブジェクト

パールのクラスはパッケージ。

package Human;
use Human;

# パッケージ名からメソッドを呼び出せる
Human->Something;

オブジェクトのコンストラクタは、blessを内部で呼び出すサブルーチン。 コンストラクタの名前は何でもよい。

blessは参照をオブジェクトとみなすために利用するらしい(よくわかっていない)

# 内部でblessを呼び出せばそれがコンストラクタ
sub new { bless {} }

# newでなくても良い
sub init { bless {} }

オブジェクトの継承には@ISA構文を利用する。
暗黙的にすべてのオブジェクトはUNIVERSALクラスを継承する。
オブジェクトからメソッドを呼び出すとき、オブジェクトにメソッドがなければ、@ISAで定義したオブジェクトの左からメソッドを探していき、 どこにも無い場合にAUTOLOADメソッドを呼び出す。

{ package Animal;
  sub cry {}
}

{ package Dog;

  # Animalを継承
  @Dog::ISA = qw(Animal);
}

# Dogパッケージにはcryメソッドが無いが、Animalを継承しているので呼び出せる。
Dog->cry;

オブジェクトに関する内容がかなり濃密なので、詳細はまた別途学習することにする。

*1:書いておかないと記憶に定着しないので…

*2:本格的にやると楽しいのだが、その分時間を消費してしまうので…

今更Perl

今更Perlなど学んでどうする?と多くの人が思われるかもしれないが、未だにPerlのお仕事がこの世には存在しているのです。

プログラマ経験も10年近くなると新しいプログラミング言語を学ぶのに殆ど時間など必要ありませんのでサクッと学んでやろうという意気込みです。*1

シンタックスレベルで学び、適当なライブラリやフレームワークを使ってなにかを作る程度という前提です、言語のコア実装に手を出すという話ではありません。)


さて、学ぶにせよ何の教材が良いのかさっぱり分からりませんでした。 とりあえずWEBで検索してみて日本語で情報がまとまっていそうなこちらを参考にREPLでPerlに触れてみました。

http://tutorial.jp/prog/perl/perlman.pdf

こちらのPDFでは本当に基礎の部分のみに焦点が当てられており、同時にソースコードリーディングしていたtokuhirom/AmonというWebアプリケーションのためのFrameworkを読み解くほどの情報は得られませんでした。

(クラス?関連、パッケージ・外部モジュールの利用方法についての情報は一切書かれていませんし、細々として言語機能もなし)

次に学ぶべきはやはり公式サイトからでしょうか?*2

perldoc.jp

チュートリアルの内容がしっかりしていて流石公式!といった佇まいですね。
この他にも開発におけるTipsなども満載で、ここに目を通すだけでPerlのお仕事は問題なくこなせそうな充実ぶりです。

これは読み進めるのが楽しみです。

*1:5年後にPerlが消えてなくなったとしても学んだ知識は形を変えて役に立つものです

*2:何故最初に公式へいかなかった!?