Laravelのドキュメントはソースコード
Webでフレームワークを使おうと思うとRuby on Railsほど優れているものはないかと思いますが、僕はアルバイト先でPHPのフレームワークであるLaravelを使って開発しています。
昔はCakePHPが多かったと思いますが、Googleトレンドを見てもLaravelがだいぶ増えてきているのがわかります。(というかPHP離れが進んでいるだけかも?)
そこで今回は、Laravelを開発するときにソースコードを見るといいよという話をします。
Laravelのドキュメント
Laravelのドキュメントは結構充実していて、全体の機能をわかりやすく説明されています。
最初に開発を始めるときはここを見ておけば問題なく開発を進めることができます。ただ関数ごとに返り値は何かとか、内部的な処理の説明はないので、もっと進んだアプリケーションを作ろうと思うとAPIドキュメントを見る必要があります。
このAPIドキュメントを読めば大体のことがわかるのですが、実はLaravelのソースは結構綺麗に描かれていて、このドキュメントを読むよりソースを読んだ方が実際の処理もわかるので僕はいつもソースを読んでいます。
ソースコードを読む
LaravelのGItHubのリポジトリはlaravel/laravelなのですが、実際のフレームワークを構成しているコードたちはこちらになります。
このリポジトリのsrc/Illuminate
以下が実装になります。例えば、EloquentORM
を使っているときに、firstOrNew
とfirstOrCreate
が実際にどのように違うのか気になったとします。そんなときはsrc/Illuminate/Database/Eloquent/Builder.phpを見に行きます。
すると簡単に両関数を見つけることができます。
/** * Get the first record matching the attributes or instantiate it. * * @param array $attributes * @return \Illuminate\Database\Eloquent\Model */ public function firstOrNew(array $attributes) { if (! is_null($instance = $this->where($attributes)->first())) { return $instance; } return $this->model->newInstance($attributes); } /** * Get the first record matching the attributes or create it. * * @param array $attributes * @param array $values * @return \Illuminate\Database\Eloquent\Model */ public function firstOrCreate(array $attributes, array $values = []) { if (! is_null($instance = $this->where($attributes)->first())) { return $instance; } $instance = $this->model->newInstance($attributes + $values); $instance->save(); return $instance; }
すると実際には$instance->save()
をしているかしていないかだけが違うことがわかります。Laravelの関数一つ一つのコードはこのくらい短く、Railsに比べるとコードを追うのがかなり楽です。
ドキュメントを見にくよりも毎回このようにソースを見ていった方が関数の仕様と中でどんな処理をしているのかをつかむことができるのでかなりオススメです。
まとめ
文系プログラマの方はライブラリがあったときに、中を読まずになんとなく便利だなと思いながら使っている人が大半だと思いますが、それではドキュメントに載っていないようなところでつまずいたときに解決できなくなってしまいます。また、ライブラリのソースを読むことでそのライブラリにプルリクを投げる機会がやって来るかもしれません。近いうちにLaravelにプルリクを投げようかと思います。
Laravelのコードは読みやすいのでぜひ皆さんも開発しながらコードを眺めて見てください。
計算順序を考慮した電卓をRubyで書く
初めての投稿になります。
情報工学科の学部生でアルバイトでフルスタックエンジニアをやっています。
最初の内容は僕がQiitaに書いた、
の話をします。
なぜ計算順序を考慮した電卓を書いたか
僕が今読んでいる本でUnderstanding Computation
という本があり、この本の最初の話はプログラミング言語のSemantics(言語学では単語とその単語の意味の関係)をRubyで簡単なプログラミング言語を書きつつ理解するという内容です。
この章を読み終えるとRubyで簡単な式を評価できるプログラミング言語を作ることができます。この章で学んだものを生かして簡単なものを書きたいなと思った時に計算順序を考慮した電卓でも作ろうかなと思いました。この計算順序を考慮するというのはコンピューターサイエンスのバックグラウンドがあれば式を木構造にして評価するというアイディアは持っていますが、文系エンジニアのような方にはなかなか難しいものがあります。
アルバイト先の会社でたまに勉強会をやっているのでネタ作りも兼ねてこのような基礎的なアイディアと、問題を解決する際にデータ構造を工夫するといいぞといういい見本になるなと思って書きました。
簡単なコード
class Value < Struct.new(:value) def evaluate value.to_i end end class Add < Struct.new(:first, :second) def evaluate first.evaluate + second.evaluate end end class Sub < Struct.new(:first, :second) def evaluate first.evaluate - second.evaluate end end class Mul < Struct.new(:first, :second) def evaluate first.evaluate * second.evaluate end end class Div Struct.new(:first, :second) def evaluate first.evaluate / second.evaluate end end def parse(equation) length = equation.length add_pos = equation.rindex('+') sub_pos = equation.rindex('-') if !add_pos && !sub_pos mul_pos = equation.rindex('*') div_pos = equation.rindex('/') if !mul_pos && !div_pos Value.new(equation) elsif (!div_pos && mul_pos) || mul_pos > div_pos Mul.new(parse(equation[0...mul_pos]), parse(equation[mul_pos + 1..length])) else Div.new(parse(equation[0...div_pos]), parse(equation[div_pos + 1..length])) end elsif (!sub_pos && add_pos) || add_pos > sub_pos Add.new(parse(equation[0...add_pos]), parse(equation[add_pos + 1..length])) else Sub.new(parse(equation[0...sub_pos]), parse(equation[sub_pos + 1..length])) end end print parse('1+2*3-4').evaluate # 3
解説
基本的に後に出てくるものほど最後に計算します。文字列を後ろからパースして最初に出てきた+
か-
を木構造のノードにして演算子の左右をそれぞれ再帰的にパースしていきます。+
も-
もなくなったら次は*
と/
をチェックしていきます。もし演算子が見つかれば再び再帰的にパースします。そして演算子がなくなったら葉として値を持ちます。
しかし肝心のポイントはそこではなく、どのように木構造を保持するかです。今回はUnderstanding Computation
と同じようにクラスのインスタンスに入れることにしました。演算子のクラスのオブジェクトがノードとなりValue
が葉となります。
これをプログラミング意味論的な言い方をするとOpereational Semantics
ということができます。Operational Semantics
はプログラムの意味を理解する時にどのようにプログラムが実行されるかというルールを定義することで理解するという意味だそうです。
まとめ
Understanding Computation
はコンピューターサイエンスのバックグランドがない人を対象にしているらしいですが、情報工学科の学生でも十分読む価値があります。大学の授業ではなかなかやらないトピックなのでこの本を通して得られる知識はコードの最適化やアルゴリズムを考える上でやくにたつと思います。
実は今年の夏にUC Berkeleyのサマーセッションに出てコンピュータアーキテクチャの授業を受けてきました。他の授業を受けていた同じ学科の友達はPythonについての授業だったそうですが、単なるプログラミングの授業ではなくプログラミング意味論の要素も入っていたようです。このサマーセッションについては別の記事で書きたいと思います。