ダウンロード - 株式会社アイヴィス

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の書籍は色々あります