カテゴリー: programming

Jakarta Commons CLI

  • Jakarta Commons CLI
    • コマンドライン引数をパースしてというCLI(Command Line Interface)
    • Options: 受け取れるオプション
    • addOptionで受け取れる引数を追加していく
    • parser.parse(options, args)とするとパースした結果を得られる

phax/ph-cssを使う

phax/ph-css の使い方

b080e264-d67f-11e4-845e-c1f3fdff6678

便利

Protocol Buffers を PHP から使う

Protocol Buffers とは

JSON, XML などは人間の目に比較的優しい形 [要出典] でデータを表現することができます。その反面、データが大きくなったり、データ解析が複雑だったりします。

Protocol Buffers は、通信や永続化などを目的に、データサイズの小ささやパース時のパフォーマンスなどを追及したシリアライズフォーマットです。データ構造はあらかじめプロトコル定義ファイル(.proto)に定義をしておき、Google が配布している protoc プログラムによって、各プラットフォーム上でのシリアライザ・デシリアライザを含めた関連コードが自動的に生成できるようになっています。

したがって利用する際の基本的な手順は大雑把に次のようになります

  1. データ構造を IDL で定義した proto ファイルを作成する
  2. proto ファイルからProtocol Buffersの利用に必要なコード(シリアライザ・デシリアライザなどが含まれる)を生成する
  3. 生成されたコードを利用したコードを書く

データ構造をはじめに定義し、そのデータ構造に応じたコードをあらかじめ用意しておくあたりが、JSON, XMLなどと異なります。

環境構築

さて、PHPから Protocol Buffers を使うために環境構築を行いましょう。まずは protoc プログラムをインストールします。

また今回利用するPHPライブラリは pear の Console_CommandLine を必要とするため、これも入れます。

最後に PHP ライブラリを composer で導入します。

インターフェース定義ファイルの作成

Google の proto3 Language Guide を見ようみまねで、簡単なものを定義してみましょう。次のように search_request.proto ファイルを作成してください。

インターフェース定義ファイルは直感的でわかりやすいので、きっと解説はいらないでしょう…。

Protocol Buffers 利用のためのコード生成

composer でひっぱってきたファイルのなかに必要なコードの生成を補助してくれるファイルがあるので、それを使いましょう。

今、ディレクトリ構造が以下のような形だったと仮定します。

vendor/bin 下 に protoc-gen-php.php というファイルが存在しますが、これを使うと簡単に必要なコードを生成することができます。さっそく SearchRequest データ構造を PHP で扱うためのコードを生成してみましょう。

すると src/Dist/Protobuf 下に SearchRequest.php というファイルが生成されるはずです。

これで準備が完了しました。

Protocol Buffers を利用する

まずは SearchRequest のインスタンスを取得し、各フィールドをセットして、シリアライズしてみます。

以上のようなコードを実行すると以下のようなバイナリが出力されます。

バイナリサイズは 30 byte でした。対応する標準的なJSONだと 77 byte あるのでおよそ半分になっていることがわかります。

またデシリアライズは次のようなコードで可能です

`

実行すると次のようになります

ちゃんともとのPOJOを復元できていますね

PHPのアレコレ

たまにしかPHPを触らないので色々問題が発生する

Java, Scala のお仕事依頼お待ちしております → @gomi_ningen

複数環境に対応する terraform のディレクトリ構成と tfstate の管理

terraform はディレクトリ内のすべての tf ファイルを実行対象とするので、環境ごとに変数を変えるなどの際には module という機能を使うと良い。このときのディレクトリ構成は terraform が公式でこれというものは定めていないので各々やっていく必要があるが、よさそうな構成は以下の2つの記事の内容だった。

後者のほうがよりシンプルで個人的には好き。さて、これらのディレクトリ構成をとった場合、 tfstate はそれぞれの環境ごとに作成される。この管理をどうするかという問題が発生する。

基本的には単純に terraform remote config コマンドをそれぞれのディレクトリに入った瞬間叩くという運用になるかと思いますが、ちとダルいので以下のようなシェルスクリプトを書くと良さげ。

それぞれ dev から実行すれば dev/terraform.tfstate を、 prod から実行すれば prod/terraform.tfstate を remote state として取り扱えるようになる。

その他

multiple provider 機能も使わねばならんかったのでリンクだけ貼っておく

terraformingを試す

AWSの管理にterraformを導入したいけれど、既存のリソースはもうすでに存在しちゃっているということは、まあよくあると思います。手で tf ファイルと tfstate ファイルをいじればなんとかやってやれないことはないですが、幸いなことにこれを支援してくれるツールが存在します。それが terraforming です。

terrraforming の導入

terraforming を取ってくる Gemfile 書いて bundle install すれば、おk。

terraforming の使い方

とても簡単。bundle exec terraforming [service_name] --profile=[$PROFILE]で既存のawsの構成通りのtfファイルのコードを生成してくれます。以下のような具合。

これを tf ファイルに追記すればよいのですが、 tfstate にこれらのリソースがあることが記されていないため、このまま plan, apply をすると既存のものを無視して構築を始めてしまいます。これを防ぐためには tfstate を適切に更新して、 plan で差分が出ない状況に持っていく必要があります。そこで terraforming iam --profile default --tfstate --merge=./terraform.tfstate とすると既存の tfstate に既存のAWSインフラの state を追記してもらえます。こわければ tfstate の backup を取っておいたほうが良いかと思います。

とても良いですねー。

terraformを試す

terraformのチュートリアルを見ながら、いろいろ試してみた記録その1。結構使い勝手はよさそうなので、こういうツールでちゃんとAWSのリソースを管理していきたい。

terraform の導入

導入は brew install terraform で OK

EC2インスタンスを立てる, 更新する, 破棄する

とりあえず簡単なところから。以下のファイルを example.tf という名前で作成する。

で、 terraform plan を実行するとこれからAWSに対して何を行うのかを表示してくれる。なにもないまっさらな状態であれば以下のような出力になるだろう。

terraform apply を実行すると、実際にリソースが作成される。さっきの example.tf を編集してたとえば t1.micro にして、 terraform plan をするとちゃんと instance_type に差分がでる旨の表示が出る。スタックの削除は terraform destroy で行ける。

リソースの依存性を扱う

以下のように、Elastic IPを設定する。Elastic IPに対するパラメタは instance しかない。そこには ${aws_instance.example.id} とあるがこれは、 EC2 インスタンスのidが埋め込まれる変数の役割を持つ。

もうすでに EC2 インスタンスは立ち上がっており、 aws_eip の部分だけ追記をして terraform plan を実行すると以下のようになり、この挙動がわかりやすい。

プロビジョニング

以下のように provisioner 内の command を設定することによりプロビジョニングを行える

まっさらな状態でこれを実行すると、file.txtがちゃんと生成される

変数

variables.tf なるファイルを作る

そして、example.tf の provider を以下のように変えてみよう

variables.tf で定義してある region についての挙動はもうおわかりだろう。問題は access_keysecret_key であるが、これは default が設定されていないので apply 時に渡す。たとえば terraform apply -var 'access_key=...' -var 'secret_key=...' のような具合だ。

また conf ファイルから読み込みたければ、たとえば dev.tfvars という名前で以下のようなファイルを作成し terraform apply -var-file ./dev.tfvars を実行すれば良い。

環境変数からの呼び出しは TF_VAR_access_key などという名前をつければいける。

出力

terraform apply を実行した結果のうち、重要な値の出力を得たい場合は以下のような形のコードを書けばよい

すると apply 時に以下のような出力が得られる

またapply後に出力だけ得たい場合は terraform output ip などとすれば良い。

Cのコードがどのように処理されるのか

プリプロセッシング

空のファイルのプリプロセッシングを進めてみる

続いて、簡単なコードを書いてみた上で…

#define を使って見ると…

#include の動きは単純にソースコードをガバッと持ってくるだけ。コメントの除去とかもこのタイミングの模様。

コンパイル

プリプロセッサの出力をソースにしてアセンブリコードを生成する。
空のプログラムを流してみる

続いて int i = 1; とだけ書かれたコード

さすがにつまらん…。単純な関数とかはこんな感じ。まあここらへんは別の記事とかで…。

アセンブル

アセンブリコードからバイナリの生成を行うフェーズ。

あっ、ハイ…って感じだ。次のコードを試してみる。

リンク

実行可能なバイナリにする。ライブラリや他の必要なコードとの結合を行う。

参考にしたページ

ありがとうございます 🙏

電卓を作る

プログラミング言語を作るの2章を読み進めた記録。興味があったけど手を出せずにいた自作プログラミング言語ですが、この記事を読んでまあつべこべ言わず手を動かそうと決心して、コードを書き始めた。成果物はここにあります。

処理系のうごき

プログラミング言語の処理系は通常以下のような流れで動く

  1. 字句解析: ソースコードをトークンの並びに分割する。字句解析を行うプログラムのことをレキシカルアナライザと呼ぶ。
  2. 構文解析: トークンの並びから抽象構文木を構築する。構文解析を行うプログラムのことをパーサと呼ぶ。
  3. 意味解析: 抽象構文木に対して、データ型などの意味的な解釈を行う。
  4. コード生成: 機械語やバイトコードなどを吐き出す

電卓プログラムの字句解析

lex というレキシカルアナライザを自動生成してくれるツールを使う。UNIX系のOSであれば最初から入っていることが多い。定義には正規表現を使う。

電卓プログラムの構文解析

yacc というパーサを自動生成してくれるツールを使う。

構文規則だけを抜き出すと以下のような感じ?

動かす

Makefile を書いた

以下のような感じ

コマンドラインから、温かみのある手動ビルドをしたいときは以下のような具合

shift と reduce

パーサーのうごきをちゃんと押さえておく。1 + 2 * 3 という入力があったときの動きは以下の通り。

  1. 1 (shift) next: AND
  2. primary_expression (reduce) next: AND
  3. term (reduce) next: AND
  4. expression (reduce) next: AND
  5. expression AND (shift) next: 2
  6. expression AND 2 (shift) next: MUL
  7. expression AND primary_expression (reduce) next: MUL
  8. expression AND term (reduce) next: MUL
  9. expression AND term MUL (shift) next 3
  10. expression AND term MUL 3 (shift) next CR
  11. expression AND term MUL primary_expression (reduce) next CR
  12. expression AND term (reduce) next CR
  13. expression (reduce) next CR
  14. expression CR (shift)
  15. line (reduce)
  16. line_list (reduce)

スタックの動き

  • 2 * 3 を reduce する際は、 term := term MUL primary_expression { $$ = $1 * $3; } の規則に従う
  • $1 = 2, $2 = *, $3 = 3 として、 新しい term には $$ = 2 * 3 が格納される
  • {} を書かなかった場合は $$ = $1 が補われる
  • つまり 1 => primary_expression($$ = 1) => term($$ = 1) => expression($$ = 1) みたいな感じになっている

管理ポリシーとインラインポリシーの違い

参考: http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access_policies_managed-vs-inline.html

管理ポリシー

  • AWS管理ポリシーとカスタマー管理ポリシーに分かれる
  • AWS管理ポリシーはよく見る 〜〜〜FullAccess とかそういうやつ
  • カスタマー管理ポリシーはそれを自分で作れる模様
  • 複数のユーザー/グループ/ロール(この3つを合わせてプリンシパルエンティティというらしい)にアタッチできるという特徴がある
  • ロールバックできる
  • バージョン管理してくれる
  • IAM内のARNを持つスタンドアロンな存在

インラインポリシー

  • 単一のユーザー/グループ/ロールにしかアタッチできない

インラインポリシーは、ポリシーとそれが適用されているプリンシパルエンティティとの厳密な 1 対 1 の関係を維持する必要がある場合に便利です。たとえば、ポリシー内のアクセス権限が意図したプリンシパルエンティティ以外のエンティティに間違って割り当てられないようにする必要がある場合などです。インラインポリシーを使用すると、ポリシーのアクセス権限が間違ったプリンシパルエンティティにアタッチされることはありません。また、AWS マネジメントコンソールを使用してプリンシパルエンティティを削除すると、プリンシパルエンティティに埋め込まれたポリシーもその一部として削除されます。

バージョン管理・ロールバック、強さあるし、カスタマー管理ポリシー強い