Ruby on Rails の紹介 2015/10 高島 亮祐 自己紹介 • 高島 亮祐(たかしま りょうすけ) • id:rst76 (twitter, hatena, github) • 日本ユニシス株式会社 2001年度入社 • 2010年くらいから Ruby / Rails に携わる(同僚のお手伝い) • プライベートでは Haskell / Lazy K ゴルファー (端的に言うと関数型厨) コードゴルフって? • 仕様を満たすプログラムを、できるだけ少ない打数(バイト数)で実装する。 • 例:自然対数の底eを100桁出力する。 27182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274 main=print$sum$36:scanl div(10^100)[1..99] (42bytes in Haskell) • 浮動小数では精度が足りないので、多倍長整数を使う • 指数関数のテイラー展開 • 高階関数のパターンにはめる(scanl) を利用する 1 a 2 3 a/1! a/2! a/3! a=10100 sum ・・・ Lazy K って? • コンビネータ論理(=型なしラムダ計算)を具現化した言語 • プリミティブは以下の3つだけ • S = λxyz.xz(yz) • K = λxy.x • I = λx.x • たとえば整数は以下のように定義できる • 0 = SK • 1 = SKK = I • (*) = S(KS)K = B • 0 * 1 ≠ 0 に見えるが・・・ • 0 * 1 = S(KS)K(SK)(SKK) = (KS)(SK)(K(SK))(SKK) = S(K(SK))(SKK) • 0 * 1 = 0 が成り立つ! • 0 f x = SKfx = Kx(fx) = x • (0 * 1) f x = S(K(SK))(SKK)fx = (K(SK)f)(SKKf)x = SKfx=x • ちなみに 1 f x = SKKfx = Kf(Kf)x = f x (チャーチ数) Lazy K の Quine (*) `S````SSSS``SS`SK``SS`SK``S`KSK```S``S`KS``S`K`S`KS``S`K`S`KK``S`K`S`KS ``S`K`S``S`KS``S`K`S`KS``S`K`S`K`S`KS``S`K`S``S`KS``S`KK``S`KS``S`KK``S ``S``SSS`SK`KK``S`KK``S``S`KSK`K```S`KSK``S`K`S``S``SKK`K```S``SS``SS`` SS``SS``SSS``SS`SK``S`KSKK``S`K`S`KK``S`K`S``S`KS``S`KK``S`KSK``S`KK``S `K`S``S`KS``S`KK``S`K`S``S`KSK``S`KSKK``S`KK``S`K`S``S`KS``S`KK``S`KSKK ``S``S``S``S``SSS`SK`KK`K``S`K`S``S``SKK`K```SS``SS``SS``S``SSS``S``SS`` SS`SK``SS`SK``S`KSKK`K``S`K`S``S``SKK`K```SS``SS```SS```SSSS``SS`SK``S` KSKK``SKK``SKKSKSKSSKKSKSKSSKKSKSKSSSKKSSKKSKSSKSSSSKKSSSSSSSSKKKSSSSK KKSSSSKKSSSSKKKSKKSKSKSSKKSSKKSSKSKKSSKKSKKSKSKSSSKKSSKKSKSSKSSSSKKSKS SKSSSSKKSSSSKKSSKKSSSSSSKKSSKKSSSSKKSSSSKKSSSSKKKSKKSKSKSSKKSSKKSSKSKK SSKKSKKSKSKKSKSSKSSSSSSKKSSKKSSKKSSKKSSKKSKSKSSSKKSSKKSKSKKSSKKSSSKKSS KKSSKSKKSSKKSKSKKSSKKSKSKSSSKKSSKKSKSSSKKSSKKSSKSKKSSKKSKSKKSSKKSSSKKS SKKSSKSKKSSKKSKSKKSSKKSKSSSKKSSKKSKSKKSSKKSSSKKSSKKSSKSKKSSKKSKSKKSSKS KKSSKKSKSKSSSKKSSKKSKSSKSSSSKKSSSSSSKKSSSSKKSSSSKKSSSSKKSSSSKKSSKKKSKK SKSKSSKKSSKKSSKSKKSSKKSKSSSKKSSKKKSKKSKSSSKKSSKKSSKKSKSKKSSKKSKSKKSKSS KSSSSSSKKSSKKSSKKSKSKKSSKKSSSKKSSKKSKSKKSSKKSSSKKSSKKSSKSKKSSKKSSSKKSS KSKKSSKSKKSSKKSSSKKSSKSKKSSKKSSSKKSSKKSSKSKKSSKKSSSKKSSKSKKSSKKSKSKKSS KSKKSSKKSSSKKSSKSKKSSKKSSSKKSSKKSSKKKSKSSSKKSSKKSKSSKSSSSKKSKSSKSSSSKK SSSSSSSSKKKKSSK (*) 自分自身を出力するプログラム じゃあ Ruby でコードゴルフを • ごめんなさい、読めません。 _="_=%p;$><<_%%_";$><<_%_ (Quine in Ruby) • Ruby についてはあまりディープな使い方をしていないので、 今日は主に Rails の話をします。 Ruby on Rails って? • Ruby による Web アプリケーションフレームワーク • 2003年、David Heinemeier Hansson が開発 • 現在のバージョンは4.2(もうすぐ5.0) Rails のよいところ • オブジェクト指向にのっとったキレイな設計 • RESTful なルーティング • 抽象度の高い O/R マッパー • 低い開発負荷 • 豊富なライブラリ • 準備された開発環境 Ruby on Rails のアーキテクチャ • • • • Webブラウザ HTTPリクエストの受け付け 適切なModelへの振り分け 結果のViewへの受け渡し HTTPレスポンスの返却 ① ⑧ データベース ② Controller ③ Model ⑤ ⑦ ④ ⑥ View • HTMLやJSONのレンダリング • 業務ロジック • DBアクセス Rails Railsの場合、原則として データベースの1テーブルに Modelの1クラス、 Controllerの1クラスが対応する RESTful なルーティング HTTPメソッド パス コントローラ#アクション 目的 POST /books books#create 書籍を1つ作成する GET /books books#index すべての書籍の一覧を表示 GET /books/:id books#show 特定の書籍を表示する PATCH/PUT /books/:id books#update 特定の書籍を更新する DELETE /books/:id books#destroy 特定の書籍を削除する GET /books/new books#new 書籍を1つ作成するための HTMLフォームを返す GET /books/:id/edit books#edit 書籍を編集するための HTMLフォームを返す 抽象度の高い O/R マッパー(1) books authors name: string author_id: integer name: stirng class Book belongs_to :author end books = Author .find_by(name: '安部公房') .books class Author has_many :books end SELECT authors.* FROM authors WHERE authors.name = ‘安部公房’ LIMIT 1 SELECT books.* FROM books WHERE books.author_id = 1 抽象度の高い O/R マッパー(2) books writings authors name: string author_id: integer book_id: integer name: string class Book has_many :writings has_many :authors, through: writings end books = Author .find_by(name: '安部公房') .books class Writing belongs_to :author belongs_to :book end class Author has_many :writings has_many :books, through: writings end SELECT authors.* FROM authors WHERE authors.name = ‘安部公房’ LIMIT 1 SELECT books.* FROM books INNER JOIN writings ON books.id = writings.book_id WHERE writings.author_id = 1 豊富なライブラリ • 例)全文検索エンジンを利用したい ⇒ライブラリを導入して以下のように書けば、インデクシングされる class Dataset searchable do text :name, stored: true text :description, stored: true time :created_at time :updated_at end • その他にも Key Value Store との連携など、様々なライブラリ が存在 準備された開発環境 • 本番環境 • APサーバ: Apache + Passenger • DBサーバ: PosgreSQL / MySQL (/ SQL Server (/ Oracle)) • 開発環境 • APサーバ: WEBrick • DBサーバ: SQLite • 環境の差異を意識せずに開発できる。 Ruby のメタプログラミング(1) • ミラノ万博アプリ:多言語対応(日英伊の3ヶ国語)が必要。 • name_ja, name_en, name_itの3つの属性からユーザに応じ て適切な属性を選択したい。 つまり↓のようなことを各属性についてやりたい。 def name(user) send “name_#{user.language}” end • これを各属性について書くのは面倒なので・・・ Ruby のメタプログラミング(2) • モジュールに定義して、取り込めば使えるようにした。 multilingual_support.rb content.rb module MultilingualSupport class Content def self.included(base) base.class_eval do def self.attr_multilingual(*attrs) attrs.each do |attr| define_method attr do |user| send("#{attr}_#{user.language}") end : include MultilingualSupport attr_multilingual :name, :description 呼出元 @content.name(@user) @content.description(@user) Ruby のメタプログラミング(3) • 動的なメソッド定義といったメタプログラミングが自由自在 (send, define_method, method_missingなど) • 使いすぎには注意が必要(黒魔術) • Rails 等ライブラリの内部はメタプログラミングの塊 参考書籍 Railsの書籍は色々あります
© Copyright 2024 ExpyDoc