ruby on rails の紹介 - 株式会社アイヴィス2015/10/14  · ruby on rails って? •...

18
Ruby on Rails の紹介 2015/10 高島 亮祐

Upload: others

Post on 10-Jul-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

  • Ruby on Rails の紹介2015/10

    高島 亮祐

  • 自己紹介• 高島 亮祐(たかしま りょうすけ)• id:rst76 (twitter, hatena, github)• 日本ユニシス株式会社 2001年度入社• 2010年くらいから Ruby / Rails に携わる(同僚のお手伝い)• プライベートでは Haskell / Lazy K ゴルファー(端的に言うと関数型厨)

  • コードゴルフって?• 仕様を満たすプログラムを、できるだけ少ない打数(バイト数)で実装する。• 例:自然対数の底eを100桁出力する。

    27182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274

    • 浮動小数では精度が足りないので、多倍長整数を使う• 指数関数のテイラー展開 を利用する• 高階関数のパターンにはめる(scanl)

    main=print$sum$36:scanl div(10^100)[1..99] (42bytes in Haskell)

    a

    1 2 3 ・・・

    a/1! a/2! a/3!

    suma=10100

  • 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``SKKSKSKSSKKSKSKSSKKSKSKSSSKKSSKKSKSSKSSSSKKSSSSSSSSKKKSSSSKKKSSSSKKSSSSKKKSKKSKSKSSKKSSKKSSKSKKSSKKSKKSKSKSSSKKSSKKSKSSKSSSSKKSKSSKSSSSKKSSSSKKSSKKSSSSSSKKSSKKSSSSKKSSSSKKSSSSKKKSKKSKSKSSKKSSKKSSKSKKSSKKSKKSKSKKSKSSKSSSSSSKKSSKKSSKKSSKKSSKKSKSKSSSKKSSKKSKSKKSSKKSSSKKSSKKSSKSKKSSKKSKSKKSSKKSKSKSSSKKSSKKSKSSSKKSSKKSSKSKKSSKKSKSKKSSKKSSSKKSSKKSSKSKKSSKKSKSKKSSKKSKSSSKKSSKKSKSKKSSKKSSSKKSSKKSSKSKKSSKKSKSKKSSKSKKSSKKSKSKSSSKKSSKKSKSSKSSSSKKSSSSSSKKSSSSKKSSSSKKSSSSKKSSSSKKSSKKKSKKSKSKSSKKSSKKSSKSKKSSKKSKSSSKKSSKKKSKKSKSSSKKSSKKSSKKSKSKKSSKKSKSKKSKSSKSSSSSSKKSSKKSSKKSKSKKSSKKSSSKKSSKKSKSKKSSKKSSSKKSSKKSSKSKKSSKKSSSKKSSKSKKSSKSKKSSKKSSSKKSSKSKKSSKKSSSKKSSKKSSKSKKSSKKSSSKKSSKSKKSSKKSKSKKSSKSKKSSKKSSSKKSSKSKKSSKKSSSKKSSKKSSKKKSKSSSKKSSKKSKSSKSSSSKKSKSSKSSSSKKSSSSSSSSKKKKSSK

    (*) 自分自身を出力するプログラム

  • じゃあ Ruby でコードゴルフを• ごめんなさい、読めません。

    • Ruby についてはあまりディープな使い方をしていないので、今日は主に Rails の話をします。

    _="_=%p;$>

  • Ruby on Rails って?• Ruby による Web アプリケーションフレームワーク

    • 2003年、David Heinemeier Hansson が開発

    • 現在のバージョンは4.2(もうすぐ5.0)

  • Rails のよいところ• オブジェクト指向にのっとったキレイな設計

    • RESTful なルーティング

    • 抽象度の高い O/R マッパー

    • 低い開発負荷

    • 豊富なライブラリ

    • 準備された開発環境

  • Rails

    Ruby on Rails のアーキテクチャ

    Controller Model

    View

    • HTTPリクエストの受け付け• 適切なModelへの振り分け• 結果のViewへの受け渡し• HTTPレスポンスの返却

    • 業務ロジック• DBアクセス

    • HTMLやJSONのレンダリング

    ① ② ③

    ④⑤⑧

    ⑥⑦

    Railsの場合、原則としてデータベースの1テーブルにModelの1クラス、Controllerの1クラスが対応する

    Webブラウザ データベース

  • 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)

    class Book belongs_to :author

    end

    class Author has_many :books

    end

    books = Author.find_by(name: '安部公房').books

    books

    name: stringauthor_id: integer

    authors

    name: stirng

    SELECT authors.* FROM authorsWHERE authors.name = ‘安部公房’ LIMIT 1

    SELECT books.* FROM booksWHERE books.author_id = 1

  • 抽象度の高い O/R マッパー(2)

    class Bookhas_many :writings has_many :authors, through: writings

    end

    class Writing belongs_to :authorbelongs_to :book

    end

    books = Author.find_by(name: '安部公房').books

    books

    name: string

    writings

    author_id: integerbook_id: integer

    SELECT authors.* FROM authorsWHERE authors.name = ‘安部公房’ LIMIT 1

    SELECT books.* FROM booksINNER JOIN writings ON books.id = writings.book_idWHERE writings.author_id = 1

    class Author has_many :writings has_many :books, through: writings

    end

    authors

    name: string

  • 豊富なライブラリ• 例)全文検索エンジンを利用したい

    ⇒ライブラリを導入して以下のように書けば、インデクシングされる

    • その他にも Key Value Store との連携など、様々なライブラリが存在

    class Datasetsearchable do

    text :name, stored: truetext :description, stored: truetime :created_attime :updated_at

    end

  • 準備された開発環境• 本番環境

    • 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)• モジュールに定義して、取り込めば使えるようにした。

    module MultilingualSupport

    def self.included(base)base.class_eval dodef self.attr_multilingual(*attrs)

    attrs.each do |attr|define_method attr do |user|

    send("#{attr}_#{user.language}")end

    :

    class Content

    include MultilingualSupportattr_multilingual :name, :description

    @content.name(@user)@content.description(@user)

    multilingual_support.rb content.rb

    呼出元

  • Ruby のメタプログラミング(3)• 動的なメソッド定義といったメタプログラミングが自由自在(send, define_method, method_missingなど)

    • 使いすぎには注意が必要(黒魔術)

    • Rails 等ライブラリの内部はメタプログラミングの塊

  • 参考書籍

    Railsの書籍は色々あります