# 繰り返し
10.times{|i| puts i }
[1,2,3,4,5].map{|i| i*2}
# 簡易Strategy
%w(ruby python php javascript).sort{|a,b| a.length <=> b.length}
# 終了処理の保証
File.open('log/development.log') do |f|
f.puts 'ERROR'
end
# DSL
describe User do
it { should be_new_record }
end
function foo(func) {
print('before')
func.call()
print('after')
}
foo(function(){ print('in function')})
ブロックは高階関数と本質は一緒。関数の代わりにコードの塊をブロックとしてメソッドに渡す。
def foo
puts 'before'
yield # ブロックが実行される
puts 'after'
end
foo { puts 'in block' }
ブロックは高階関数と違って複数わたせない。どうしてもって時はlambdaかprocを使う。
def foo(proc1,proc2)
puts 'before'
proc1.call
proc2.call
puts 'after'
end
foo(lambda{ puts 'proc1'}, lambda{ puts 'proc2' })
class Person
include ActiveModel::Validations
attr_accessor :name
validates :name, :presence =< true
end
Person.new.valid? #=> false
ガァガァうるさいならそいつはアヒルだ
二郎を食べるならそいつは(ry
class Logger
def self.write(out, log)
out.write log
end
end
File.open("hoge", "w") do |f|
Logger.write(f, "log") # ファイルに書き込み
end
Logger.write($stdout, "log")
Q. current_userなんでメソッドどこにも定義してないんだけど
A.
class_eval <<-METHODS, __FILE__, __LINE__ + 1
def authenticate_#{mapping}!(opts={})
opts[:scope] = :#{mapping}
warden.authenticate!(opts) if !devise_controller? || opts.delete(:force)
end
def #{mapping}_signed_in?
!!current_#{mapping}
end
def current_#{mapping}
@current_#{mapping} ||= warden.authenticate(:scope => :#{mapping})
end
def #{mapping}_session
current_#{mapping} &s;&s; warden.session(:#{mapping})
end
METHODS
RubyのライブラリやRailsとRailsのプラグインではちょこちょことメタプログラミングが使われている。なんだかんだで、ライブラリのコードを読まないとどうしようもない時がある。バグとか。そういう時にある程度読み解くだけの理解は必要。
class Foo
end
Foo.class_eval <<-METHODS
def hoge
puts 'hoge'
end
METHODS
Foo.new.hoge #=> hoge
class Foo; end
class Bar; end
Foo.class_eval <<-METHODS
def foo
puts 'foo'
end
define_method :foo_2 do
puts 'foo 2'
end
METHODS
Bar.instance_eval <<-METHODS
def bar
puts 'bar'
end
define_method :bar_2 do
puts 'bar 2'
end
METHODS
Foo.new.foo
Foo.new.foo_2
# Bar.new.bar #=> undefined method
Bar.bar
# Bar.bar_2 #=> undefined method
Bar.new.bar_2
class Hoge; end
obj = Hoge.new
class << obj
def singleton_method
'singleton'
end
end
これが定義されてる場所はどこだろう
特異メソッドは特異クラスにいる
class Object
def eigenclass
class << self; self end
end
end
obj = Hoge.new
obj.eigenclass # 特異クラス
class Hoge
class << self
def class_method
puts "class_method"
end
end
end
Hoge.class_method #=> class_method
まとめるとeval族やmethod_missingなどの挙動とRubyのオブジェクトモデルを把握しておくと捗るよ
正直、メタプログラミングRubyを読めばOKです
Railsの標準の枠組みに沿って設計・実装することをレールに乗ると表現したりする。代表的なものに命名規約がある。テーブル名を単数形にしたりするとちょっと面倒。
| テーブル名 | line_items |
|---|---|
| クラス名 | LineItem |
とは言え、2系のころよりはレールから外れても平気になった。例えばActiveRecord以外を使うとか。
基本はRailsの規約に従うこと、提供されている機能を素直に使うことが重要。
大体のことはRailsGuidesやAWDwR、APIDocに書いてある。最終手段はコードを読む。Railsのリポジトリをcloneしておこう!
resources :users
| Verb | Path | Action |
| GET | /users | UsersController#index |
| GET | /users/new | UsersController#new |
| POST | /users | UsersController#create |
| GET | /users/:id | UsersController#show |
| GET | /users/:id/edit | UsersController#edit |
| PUT | /users/:id | UsersController#update |
| DELETE | /users/:id | UsersController#destroy |
form_forなどもこれを基準に設計されている。よほどの理由がない限り、RESTfulにしよう。
この辺はRails云々よりRESTの理解が重要なのでWebを支える技術を読もう。
とりあえずScaffoldが生成するコードを読んでみよう。あれがRailsで一番シンプルなコード。
ルーティングがどうなっているのか、createやupdateの時、どういうパラメータがコントローラに渡ってきているのか(log/development.logにでてる)、form_forがどう使われているのか、色々と得るものが多い。
ユニットテストはRSpecで書く。主にモデル。コントローラはあまり書かない。コントローラにロジックはあまり書かないため。
エンドツーエンドテストはRSpec requestとcapybara-webkitでやる。
基本はcapybara-webkitとかで頑張る。JSの単体テストは色々検討中だけど、JasmineかJsTestDriverあたりかなぁという気がしている。
RubyのライブラリやRailsのプラグインは移り変わりが速い。
例: jeweler使えばいいとか思ってたのに、bundlerのせいでオワコン扱いされてた
例えば、@user.saveの時に同時になにか処理を行なわせたい時にsaveメソッドをオーバーライドせずにbefore/after_saveを使う。
class User > ActiveRecord::Base
def save(*args)
puts 'before'
super(*args)
end
def before_puts
puts 'before'
end
before__save :before_puts
end
個人的に割とこういうのは感覚的に身についてしまっているので、文書化しようとしてもそもそも意識にあがってこないし、数も多い。
なのでRailsに詳しい人とペアプロ、レビューできる環境に身を置くのが手っ取りばやい。
コードを読むにしても、アプリケーションのコードあまり公開されてないので厳しいかも。
結局はMVC、RESTfulアプリケーション、オブジェクト指向の原則に従って実装しようって感じ。テストも重要。
既にあるRailsの機能はRailsレシピブックから大体逆引きできるのでそこから探そう。あとはAPIDocかコードを読むしかない。
エッヂな機能はCHANGELOGやgitのlogをみよう。運がよければ誰かがブログに書いてくれたりもする。