「アンダースタンディング コンピュテーション」演習環境を整える

この本は、情報系の大学の、オートマトンと計算理論にあたる部分を自習できる教材である。具体的にはRubyのREPL環境で、コンピュータを作っていくことになる。ただ、Ruby標準のREPLであるirbはコーディングには貧弱なので、少し準備してみた。

irbの代わりにpryを使おう

pryはirbと比べて以下の点で有利だった。

  • シンタックスハイライト
  • 入力補完
  • 途中、vimで編集可能
  • コードのインポート、エクスポート

Home · pry/pry Wiki · GitHub

$ gem install pry

pryコマンドで開始できる。

pryの出力方法を変更する

pryでそのまま実行しても、本と同じ出力を得られない。本では構文木構築の結果をirbの実行結果として

<<1 * 2 + 3 * 4>>

のように表示させるのだが、pryだと各オブジェクトの詳細まで出力してしまって、

=> #<struct Add
 left=
  #<struct Multiply
   left=#<struct Number value=1>,
   right=#<struct Number value=2>>,
 right=
  #<struct Multiply
   left=#<struct Number value=3>,
   right=#<struct Number value=4>>>

となってしまう。

元のirbと同じように出力するには、~/.pryrcに以下を記述する。

Pry.config.print = proc { |output, value| output.puts "=> #{value.inspect}" }

元ネタ: IRB Like Output in Pry

途中で中断したり、再開したりしたい

この本では、最初は空のクラスを作って、徐々に
モンキーパッチングで機能を追加->確認、追加->確認というふうに繰り返す。だから、クラスの全体像がわかるコードは登場しない。また、一旦REPL環境を閉じてしまうと、また最初から書き直しになってしまう。

方法A. モンキーパッチングによる追記はvimで、確認はpryで行うようにする。

いくつかやりかたがあるが、この方法の場合、クラスの書き間違いを修正しやすい。

1. vimを呼び出せるようにする

~/.pryrcに追記

Pry.config.editor = "vim"
2. 先にファイルを作る
$ touch simple.rb
3. 読み込む
pry(main)> require './simple'

または、pry起動時のオプションで渡す:

$ pry -r './simple'
4. クラスの追記
pry(main)> edit simple.rb

これでvimが開く。本のように、モンキーパッチング的にclass Numberを何回も書いていってもいいだろうし、class Number 〜〜 endの中に追記していってもいい。

(元から別ウィンドウで編集しててもOKな気がする。)

この時、ファイルを上書きするたびに読み込み直されてしまうので、クラス二重定義エラーが出る。

class Number < Struct.new(:value)
end

class Add < Struct.new(:left, :right)
end

class Multiply < Struct.new(:left, :right)
end
pry(main)> edit simple.rb
TypeError: superclass mismatch for class Number

仕方ないので、最初のスーパークラスを持たせる部分だけはInclude guard的なことをしておく。23ページのコードだったらこんな感じ。

unless defined? Number
  class Number < Struct.new(:value)
  end
end

unless defined? Add
  class Add < Struct.new(:left, :right)
  end
end

unless defined? Multiply
  class Multiply < Struct.new(:left, :right)
  end
end

class Number
  def to_s
    value.to_s
  end

  def inspect
    "<<#{self}>>"
  end
end

class Add
  def to_s
    "#{left} + #{right}"
  end

  def inspect
    "<<#{self}>>"
  end
end

class Multiply
  def to_s
    "#{left} * #{right}"
  end

  def inspect
    "<<#{self}>>"
  end
end

こうしておけば、editコマンドによる編集後の自動再読みでエラーは出なくなり、

pry(main) > edit simple.rb

さらに、クラス名を指定して編集できるようになっている。

pry(main) > edit Number       #vim起動時に自動でclass Numberの行まで移動
5. エディタを閉じて、実行してみる

リロード操作は不要

pry(main)> Add.new(
                         Multiply.new(Number.new(1), Number.new(2)),
                         Multiply.new(Number.new(3), Number.new(4))
                       )
=> ...(出力)...

4, 5の工程の繰り返しで作業していく。

参考: Ruby - Pry上でreload!要らずのファイル編集 - Qiita

方法B. 実行履歴を保存、リロードする

この方法の場合、書いたクラスの完全版がわかるコードは得られないので注意。REPLの臨場感は損なわないのでサクっと進みたい人はいいかも。

デフォルトでpryは~/.pry_historyに履歴を溜め込んでいる。

History · pry/pry Wiki · GitHub

historyを眺め、hist --replay [m..n]というコマンドで再生できる。別ファイルに保存したい場合はhist --save [m..n] FILENAME で保存できる。

電子立国と、ハードウェア設計者の私

電子立国「第05回 8ミリ角のコンピューター」(01 of 02) ‐ ニコニコ動画:GINZA

久々に休日に休んでいるので、有名なNHKドキュメンタリー "電子立国 日本の自叙伝"(1991年放送)を見ていた。

文系のNHKスタッフがものすごく勉強して番組を作っているのが分かるし、実験の再現なども行い産業史の資料として貴重っぽい感じだ。

"第5回 8ミリ角のコンピューター"では、IntelのCPUの元となる4004の開発者、嶋&ファジンのインタビューを長尺で見れる。



ところで、私はハードウェア系の研究室にいる修士の学生なのである。(ハードウェアというのはここでは狭義の意味で、デジタル回路設計のことである。はんだごては使わず、論理設計が主な仕事だ) が、ハードウェアを研究するモチベーションがどうも弱い。いくつかある要因のうちの1つが、ハードウェア(回路設計)界のスターを知らないことだ。ソフトウェア界のスターならば無数に挙げられるのに。

それがぼくには楽しかったから (小プロ・ブックス)

それがぼくには楽しかったから (小プロ・ブックス)

私はこの、Linusの自伝本を立ち読みしたことが、コンピュータの世界に進むきっかけだった。それまで私はVisual Basicで簡単なプログラムを書いたくらいの経験しかなかったけれど、LinusのはじめてのOSがコンソールになにか返してくる瞬間の喜びの描写なんかはとても共感できた。それから、OSSの教祖とか、カーネルハッカーとかは神だと思いはじめた。

そういうのが初期衝動であったので、現在ハードウェアの世界に転身してからというもの、魅力はどこにあるのか、スターはどんな人々なのかというのが見えず、不安であった。

ドキュメンタリー動画に話を戻す。プロセッサ設計にとってはまさに嶋さんやファジン氏がスターなのだ。そして彼らが回路設計で身を削った苦労というのは、私がやっていることとさほど変わらないものだった。設計したものが実際うまく行くのか?リセットシグナルを送るまで分からない。信号を確認できた瞬間というのはやっぱり共感できるものである。その後、Intelが大きくなって、みんながこぞってx86バイナリを作ってみたり読んでみたりしてるわけで、ソフトウェアと地続きになっていくわけだ。

ところで、ソフトウェアから入った人間として、苦労した&気づいたこともある。当時の回路設計者というのは紙に設計して、論理設計から波形の確認まで数ヶ月もかかっていた。私たち、現代の回路設計者は、論理を組んでからシミュレーターで見るまで一瞬で行える。それでも私は慣れなくて大変だった。ソフトウェアの場合は結果を出すまでが超効率化されていて、むしろテストを書いてから実コードを書き、コードの上書き保存と同時にテスト結果が出るほどだ。ハードウェア業界はエンジニア人口が少ない上に、特許とか知的財産で商売してるので、そういう作業効率化のノウハウがほとんど共有されていないことに気づいた。

逆に回路側の視点も持てた。オープンソースハードウェアとか言葉は流行ってるけれども、Arduinoとかも実際の使われ方はマイコン時代と変わらない。ハードウェア記述言語をOSS界隈の人々がホビーとして書くようなレベルには浸透してないらしい。作ったものを見せるだけではなくて、たくさんの人の手で、ひとつのコードをレビューしたり改良していくような文化が無ければ、上述のような作業の効率化の登場は無いだろう。なんか出来ないかなぁ、などと考えているんだけど、このへんの横断が出来たらもう少し楽しくなってきそうだ(future work)

とりあえず、コンピュータというのは、歴史を知ると楽しく思える部分が多い。情報系の学生は産業史を見てみると役に立つかもしれないので、おすすめだ。

Levelopができるまで

4月くらいから開発に参加していたプロジェクトが公開されました。

Levelop.org


練習メニュー共有サービスです。クックパッドのスポーツ版のようなものですね。機能が充実してきたらスポーツ以外にも、楽器や勉強法なども扱えるようにする予定です。

エンジニアとして参加したので作業プロセスや技術的側面にフォーカスして、公開までの道のりを紹介しようと思います。

プロジェクト参加

2014年3月末に、新しいウェブサービス立ち上げを構想しているという二瓶氏に誘われて参加しました。その時点で二瓶氏はすでに開発中のプロジェクトがあり、それの機能追加などをする予定でした。二瓶氏は企画、開発、運用のスキルがありますが一人では作業量が多いので、ちょいちょい声をかけた人に手伝ってもらうというスタイルでした。その時点では他にデザイナーの方がいらっしゃいました。

私はいくつか開発のアルバイトの経験はありましたが、企画から実装、運用まで一切の不満無くできるかというと結構難しいです。しかし、スタートアップ的にやっていくなら、進行方法に対して直接議論すればいいし良い経験になりそうだと思い、喜んで引き受けました。人数が少ないがゆえ好きな領域でスキルを試せるのも良いです。

プラットフォーム

  • レンタルVPS
  • Ruby on Railsバックエンド
  • AngularJSフロントエンド


作業ツール

  • Google Drive: 調査資料、ミーティング資料
  • KanbanFlow: タスク管理
  • Bitbucket: リポジトリや全体のプロジェクト管理

自分の担当箇所

  • SeleniumによるE2Eテストや実施方法,どこまで網羅するかの検討


基本はリモート作業です。週1,2回、大学のフリースペースを借りたりして対面で開発やミーティングをしました。

何回かに一度は知人の学生数人を呼んで、テスト方法について議論したりしていました。E2Eテスト、ユニットテスト、コストのトレードオフなどをまとめられ、かなり有意義でした。

f:id:ishn:20140426142257j:plain

毎回対面で作業する都度、新しいサービスの企画を考えて日々記録していくという遊びも取り入れました。

いったん破棄して再度ブレインストーミング

で、途中まで作業してたのですが、サービスのモデルに致命的な欠陥が見つかり、一旦破棄されました。

何本かアイディアをストックしていたし、既存OSSを応用させてすばやく開発しようという方針になり、改めて5人くらい知人を集めて新サービスのブレインストーミングから始めました。

  1. ソースを応用できそうな既存OSS調査(CMSみたいなのとか)
  2. ターゲットになりそうなユーザー層の調査
  3. OSSとユーザー層の組み合わせのうち最も集客が見込めるところは?

というプロセスを経て、何本か実践できそうなのが見え、そのうちのひとつがLevelopだったわけです。Levelop以外にも、開発リソースさえあればいけそうなアイディアもストックできました。

このころから体制がおおよそ以下のようになってきました。

  • 主力の企画/開発 - 二瓶氏
  • デザイナー x 1
  • フロントエンドエンジニア x 1
  • インフラエンジニア x 1

私はミドルウェアの運用をしたかったので意向を汲んでもらい、インフラエンジニア的な部分を担当することになりました。やったね!

開発

クックパッドライクなCMSレシピブック をforkして作りこみました。これはDjangoで記述されていたので自動的にDjangoプロジェクトになりました。

AngularJSの学習コストが高かっただけに、言語ごと変わってしまったのは大変ですが、二瓶氏が技術よりもサービスに主眼を置いているのでほとんどモチベーション低下を起こすことはありませんでした。この姿勢は大事だと思いました。

コミュニティ機能の実装、新しいモデルに対するテストの調整などがアプリケーションのほうのタスクになりました。

フロントエンドはJSライブラリによるCacooみたいな作図機能の導入がありました。低い実装コストで、見栄えの良い機能ができました。

私は継続して

  • 機能追加
  • 負荷テスト方法の検討
    • 調査資料から、ピーク時のセッション数、運用するとDBはどれくらいのデータを保持するか、sqliteは十分な速度を出せるか?などを考慮

などを行いました。まだ負荷テストは実施できてないんですけどね。

公開の準備

私は直前で

  • デプロイ方法のドキュメント化
  • サポート用のメールサーバー
  • SSL設定
  • Facebookページの作成

なんかを行いました。

プログラム的な部分はあまり貢献できなかったのですが、SSL設定とか普段触れることない部分が経験できました。

課題

作業時間をいかに取るか

研究で忙しい時期は週2度も集まれませんから、毎日30分作業するという方式を導入しました。しかし夜は疲れてしまってほとんど作業にならないという日が続きました。今は週2回を使えるのでいいですが、今後も工夫が必要です。

仕様の共有

現在、ER図をCacooで管理しています。CacooやGoogle Driveのようなツールが充実していて、情報共有の方法はかなり簡単になりました。しかしフルタイムで時間を使えないので、ソースコードリーディングだけで結構時間がかかってしまい中々実作業に入れませんでした。一方でコミット前に各種UMLを書くというのはオーバーヘッドが大きすぎる。

RDocのような仕様書自動生成ツールを導入してみればいいのでしょうか?仕様共有のうまい方法は調査したいですね。

今後

練習メニューの種目は現時点で少ないですから、フィードバックをもとに機能拡充をしていきますが、それ以外で行いたいのは、

  • 負荷テスト生成して、今のVPSプランでどれくらいのアクセスがさばけるか
    • 結果によって別のプランにする
  • Djangoがアレなのでまるごと書き直したい(時間かかりそう)

です。

DjangoWordpressのような思想で設計されていて、tumblrやpinterestのような、毎日の記事投稿を管理するようなモデルに向いています。Levelopは割とアプリケーション然としているので、今後拡充していくうちにDjangoは不利になりそうです。また、APIとフロントエンドの分離も行いたいのですね。

ゆくゆくはMEAN(Mongo, Express, Angular, Node)スタックでの完全書き直しができたらなぁと思ってます。ただ、これは開発リソースが磐石にならないと難しいですね。

あと最近は
tecoビジネスカフェ というコワーキングスペースをみつけたので利用しています。

今後はLevelopで使っている技術ネタをもう少し具体的に書いていこうと思います。

NRIのOSS開発合宿に参加してきた

イベントレポートです。

開催要項

  • OSS開発合宿2014
  • 日程: 2014年6月20日-22日
  • 場所: 神奈川県 マホロバマインズ三浦 というホテル
  • 人数: 30人くらい?
  • やること: 1チーム4人前後で、20時間くらいで好きなものを作って発表するだけ

感想

WebRTCとか流行りの技術を使ったチームとか、パターン認識、フィルタなどを応用したチームが多くとてもレベルが高くて楽しかったです。具体的にどのようなチームがあったか、あとでThinkITで記事になるそうなので、そちらをご覧ください。

あと私は就職したことがないけれど、大企業のお仕事ってどんな感じなのか直接聞くことができたのはよかったと思います。

NRIの人々は、途中で投げ出さないで真剣に相手の話を聞き、検証する姿勢を全員持ってて、とても元気になれました。学生同士にはないスリルがありますね。

宿泊の関係上、参加費は安くないですが、また来年も行きたいと思ってます。

成果物

AWS上で動かしてたものです。


アプリのログからテスト生成するシステム

ishikuro/devcamp2014_teambeko · GitHub


別のWebアプリケーションサーバーを監視,管理するWebアプリケーションです。未完成。

帰宅後まだ再現できていないという。書きかけだけど自分でも使いたいものだったので暇をみつけて開発続行したいですね。

やったこと(日記帳)

写真をとり忘れたのでほとんど文字だけです。

OBの先輩に誘われて参加することができました。交通や現地でのコーディネートなどほとんどやっていただいてたので、とてもありがたいことです。

[20日昼]移動

会津から高速バスと電車で三浦まで行きました。神奈川は初めてでしたが、緑が多いし陽射しが明るくて過ごしやすそうなところでしたね。開催地のホテルには夕方ころ着いて、休んでました。

[21:00]開場

参加者まばらに集合です。NRI現職の方々がお仕事で半数くらい定刻に集合できなかったことが印象深いです。業務で忙しい上に合宿でがっつり作りますからね。むしろ凄い。

[23:00]開催

はじめ、前回のあらすじ、開催要項の説明の後、各チーム数分で作りたいもの発表を行いました。

チームについて

最初7人のチームに入れさせてもらってたのですが、準備段階からさらに2チーム(4:3)に分かれて別々なものを作ることになってました。
が、さらにそれから2分割(3:1)し、それがさらに2分割(2:1)になり、気づいたら、いとうたかゆきさんと私二人のチームになってました。これから徐々に合宿では仲間割れチームとして認知されていきます。

今回予定してたやつ: アプリのログからテスト生成するシステム

f:id:ishn:20140703134840p:plain
このようなやつです。作りたかったのは、別のWebアプリケーションサーバーを監視,管理するWebアプリケーションです。

  • Rails等の対象アプリケーションのログをfluentdで監視
  • MongoDBに放り込んでおく
  • MongoDBから当該テスト生成システムがデータを抽出して、視覚化
  • HTTPメソッド, パラメータ, それに対する応答を元にワンクリックで、負荷テストスクリプト生成, 簡単なRSpec生成ができる

[21日未明]環境構築

いとうさんがAWSを用意してくれたので、手分けして

  • デモ用Railsアプリ(ログ監視対象になる)
  • fluentdでRailsのログをパースする準備

などの環境構築をしていました。

主に私はデモ用Railsアプリを探してました。URL失念しましたが、Twitterクローンのようなものを使いました。最終的には負荷のログも必要なデータだったので、負荷テスト生成もしたかったのですが時間がなくてできませんでした。

この日はこの作業を終わらない限りは俺たちの朝は来ないというつもりでやってましたが、朝食の時間ころにやっと終わりました。ご飯の前の朝風呂が気持ちよかったです。

[7:30くらい]朝食、仮眠

ビュッフェ形式の朝ごはんを食べたあと、仮眠しました。どこで寝たのかは覚えていませんね。

[10:00くらい]再開

f:id:ishn:20140621125302j:plain

正規表現をOBの先輩にやってもらったおかげで、fluentd側からRailsのログをパースする仕組みが動き始めました。

Railsのログ -> fluentd -> 必要な情報を構造化してMongoDBに保存

ここまでできています。後半は、

MongoDB -> Node.jsでNVD3用にデータ加工 -> フロントエンドで受け取り描画

また、フロントエンドから"テスト実行"ボタンを押すと、対象Railsアプリへなんらかのアクセスを飛ばす部分も作ります。

[12:00]中間報告と昼食

チーム細分化の報告をここで改めてしました。

[13:00]大詰め

MongoDBからのJSONをパースしてNVD3が読めるような形に送り出す部分で久々にプログラミングしたなぁという気持ちになりました。伊藤さんにフロントエンドと仕上げとプレゼン作成してもらってました。

[19:00]開発終了, 宴会

宴会場にプレゼンを持っていって、およそ10組のチームがプレゼンしました。どのチームもレベルが高いし、見せ方もうまかったですね。とにかく笑いがあって腹筋が痛かった。その上技術的にも高度だったり、丁寧に作りこんだりしてました。

[夜]7人チーム再会しておしゃべり

ホテルのチーム別個室に戻りました。

この7人チーム、実は私以外はNRIの同期チームなのです。仕事や技術のことについてガチトークが何時間も続いていました。

部外者の私も快く輪に入れていただいて、少し打ち解けられました。

[21日10:00]結果発表

つれてきていただいたOBの先輩のプロジェクトが努力賞取れました。レッドブルTall * 24本セットだったのですが、彼はエナジードリンク飲まない派だったので分配してました。

[12:00]BBQ

あとは浜辺でBBQでした。いろいろな技術的バックグラウンドをもった方と話せて満足です。

[13:30]会津へ戻る

あとはまた高速バスで帰りました。会津着は23:00でした。

- おわり -

Jekyllを試してみた

Jekyll基本チュートリアル

参考: http://melborne.github.io/2013/05/20/now-the-time-to-start-jekyll/

インストール

$ rbenv exec gem install jekyll

開発サーバの起動とファイル監視

$ mkdir tut
$ cd tut
$ rbenv exec jekyll serve --watch

生成

以下は作成、変更するたびに自動的にコンパイルされる。

最小
$ vim index.md
---
---
#Hello World
レイアウト作成

index.md (---に囲まれた部分はYAML)

---
layout: default
title: hi
---
# Welcome

_layouts/defaults.html

<!DOCTYPE html>
<head>
  <meta http-equiv="Content-type" content="text/html; charset=utf-8">
  <title>{{ page.title }}</title>
</head>
<body>
  {{ content }}
</body>
設定

_configに書く。

慣れてきたら

開発

開発マシン
$ rbenv exec gem install jekyll
$ rbenv exec jekyll new mysite
$ cd mysite
$ rbenv exec jekyll serve --watch #しながら、ファイルを編集

デプロイ

https://www.digitalocean.com/community/tutorials/how-to-deploy-jekyll-blogs-with-git

サーバ側
$ cd ~/
$ mkdir -p repos/mysite.git
$ cd repos/mysite.git
$ git init --bare

hooks/post-receive

#!/bin/bash -l
GIT_REPO=$HOME/repos/mysite.git
TMP_GIT_CLONE=$HOME/tmp/git/mysite.git
PUBLIC_WWW=/var/www/nginx-default

git clone $GIT_REPO $TMP_GIT_CLONE
jekyll build --source $TMP_GIT_CLONE --destination $PUBLIC_WWW
rm -Rf $TMP_GIT_CLONE
exit

./hooks/post-receiveを実行してみてうまく行くか試してみる。パッケージの不足やパーミッション設定の見直しが必要になるかもしれない。

開発マシン側
$ git init
$ git add .
$ git commit -m “initial commit”
$ git remote add mysite [repository] #書式はgit help remoteに書いてる
$ git push mysite 

JavaScriptパターン

著作権侵害にならない程度に読書ノートを書く。

JavaScriptパターン ―優れたアプリケーションのための作法

JavaScriptパターン ―優れたアプリケーションのための作法


ECMAScript5対応。本書のサンプルコードは"use strict";している前提。

私が感じた想定読者

  • 構造化されたJSコードを書きたい人向け。つまりDOM操作だけではなく、Server Side Javascriptなど。

解説されるパターン

以下、内容ノート

Javascriptの概念

  • オブジェクト
    • プロパティをもつ
      • プロパティはオブジェクトである
      • メソッドはプロパティであり、オブジェクトである
    • ネイティブオブジェクト: ECMAScript標準
    • ホストオブジェクト: DOMなど
  • クラスは存在しない (GoF曰く"クラス継承よりもオブジェクトのコンポジションが好ましい")
    • 継承にはprototypeプロパティを使う

実行環境

  • JSLint
  • FirebugとかのJS Console上で動かせる

必須パターン

for (var i = 0, max = a.length; i < max; i += 1) { ... }
return { //改行を入れない。自動的に;が付加される可能性がある
  "key": "value";
}
  • 命名規則(この辺はプロジェクトによる)
    • コンストラクタは大文字始まり MyConstructor()
    • メソッド,プロパティはキャメルケース getHoge(), myValue
    • 言語仕様に無いもの
      • 定数 MAX_LENGTH
      • プライベートメンバ _setNext() など

オブジェクトリテラル記法を使う

関数

  • コールバックパターン
    • コールバック引数では()を付けない。つけると即時実行されてしまう。(無名関数のコールバックでは大丈夫)
      • コールバックになる: myFunc(callbackFunc)
      • 実行された値が入ってしまう: myFunc(getValue())
  • 戻り値を関数にする
    • return function () { ... } とすると、上位の関数はクロージャーを作成しプライベートプロパティを保持する
  • 使いどころが難しいやつ(私感) このへんは用語をぐぐるためのメモ程度
    • 自己定義関数
    • 即時関数: グローバル変数を残さずに処理を包む
      • 処理に使う変数のスコープが限定されるので、初期化処理に便利
      • クロージャーと組み合わせたり、オブジェクトプロパティの値として使ったりすることもできる
(function () {
  // inner scope
})();
    • 即時オブジェクト初期化
    • 設定オブジェクト: 引数を連想配列の形式の単一オブジェクトにする
    • カリー化 ここでの"カリー"はHaskell Curryに由来する
      • 同じ関数をほとんど同じパラメータで呼び出している箇所があるとき便利

名前空間

  • var hoge = fuga;をいきなりグローバルで書かずに, MYAPP = {}; MYAPP.hoge = fuga;みたいにするべき。工夫して、上書きチェックもできるとよい
  • コンストラクタ関数でクロージャーを作成すればプライベートメンバを作れる
  • prototypeプロパティ内に記述したものは、newしてもメモリを共有する

継承

  • ES5の場合
var child = Object.create(parent, {prop: "new property"});
  • 様々なJSライブラリにも実装例がある

メソッドのコンポジション

  • call()/apply()を使う
  • ES5ではbind()を使う

GoFデザインパターン

Javascriptは簡単にGoFデザインパターンを構築できる。

読み解くには先にJavaなど静的型付け言語で勉強しておくのもいいと思う。ただ、この本だけでも実例付きで簡単に説明してあるので、どちらを先にやってもいい。

AngularJSなどのライブラリを使う時も定番パターンを知っていれば理解が早そうだ。

本で紹介されているのは9パターン

  • シングルトン, ファクトリ, イテレータ, デコレータ, ストラテジー, ファサード, プロキシ, メディエータ, オブザーバ

DOMの扱い

ライブラリ作者は読んだほうがいいかもしれないが、素のJavascriptでDOM操作する気にはなれないのであまり読んでない。新規にWebのプロジェクトを行うのであればモダンなライブラリに任せたほうが無難。

ブラウザ間差異の吸収コードをエンジニアが書くというのがそもそもおかしいように思う。他の言語で例えるなら、CPU命令セットの違いを考慮してPythonを書くの?って感じだ。

確かにアーキテクチャまで理解しているプログラマのほうが優秀なのは分かるんだけど、Web界隈のそれは単にプラットフォームとロジックの分離が洗練されていないだけじゃんか...

感想

買いだと思う。パターンは言葉で表せるものもあるが、コードで確認しないとわからないのもある。目的志向で解説してあるから有効な場面を想像しやすい。

パーサーをつくること(2)

http://www.oki-osk.jp/esc/go3.html
http://www.prefield.com/algorithm/string/parser.html

再帰下降型構文解析が簡単らしいという情報を手に入れた。

ここで、LL(1)とか文脈自由文法とかがキーワードとして出てきて、あぁ、オートマトンの教科書を読まなければならない、と感じる。今晩は明日に差し迫った課題があるので深追いはしないことにした。

ロジックの例はここにあった。
http://www.cs.info.mie-u.ac.jp/~toshi/lectures/compiler/parsing.html

作りたいものの仕様を振り返る

さて、今回作りたいものはどの程度、"プログラミング言語"っぽいのだろう?おそらくそこまで本格的な知識は必要ないはずだ。

  • Apple-I Operation Manualによると、モニタプログラムには15種類のコマンドがある。
  • メモリは0024~002B, 0200~027F, FF00~FFFFが予約されていて、それ以外には自由に読み書きできるようだ(多分)。
  • 各番地にはHex2桁=8bitの値が保持される。
  • 次のトークンの先読みは必要ない。コマンドの最初に来るのは, {前回のポインタのupdateを意味するHex || . || : }のみ。
  • トークンにあたるものは、
    • 00~FFのHex2桁の値 (これ単体だとアドレスを表示, :の右に使われると値として見られる)
    • . (範囲指定, A0.A3 でA0,A1,A2,A3を表示)
    • : (データ保存 A0:FF でA0番地にFFを保存)
    • b (マニュアル上表記はbだが実際は空白文字を意味する。連続表示したり、連続配置したりする)

.と:は左のオペランド省略で前回指示したポインタの一つ次を指して処理を行う。

これ、手元にマニュアル無いと全然意味不明ですね。ちなみに手元のスキャンには、誤植が残ってたりする。

とりあえずそんなことをアタマに入れて、明日の合宿を受けて、また報告します。