2014年5月22日木曜日

Rubyのクラスインスタンス変数ヘ(^o^)ノ

Rubyではクラスで@valueとすることで、インスタンス変数として使うことができますよね?

んじゃ、ちょっと試してみましょう

class Foo
  def bar(val) 
    @value = val
  end
end

instance_variablesメソッドでインスタンス変数を取得しましょう
$ foo = Foo.new
$ p foo.instance_variables # => []

あれ?

barメソッドを呼び出してみましょう
$ foo.bar("murajun")
$ p foo.instance_variables # => [@value]

何が言いたいかというと、インスタンス変数はクラスにはいないよー

オブジェクトにいるんだよー














( ̄(エ) ̄)彡☆

参考
Object#instance_variables



2014年5月20日火曜日

RubyのArrayで条件式に一致する要素を抽出ヘ(^o^)ノ

Arrayでselectメソッドを使って、条件式に一致する要素を抽出してみましょう

普通にやっても味気ないので、2パターン書いてみました

どっちでもあんまり変わらないけど...(;・∀・)

こんな感じ


( ̄(エ) ̄)彡☆

Rubyで動的メソッド define_method編ヘ(^o^)ノ

Rubyでdefine_methodで動的にメソッドを作る

こんな感じ


共通部分をまとめるのに便利

( ̄(エ) ̄)彡☆

2014年5月16日金曜日

Rails generate model オプションのparentを使ってみたヘ(^o^)ノ

rails generate modeのparentオプションを調べてみたヘ(^o^)ノ

オブジェクト指向か?と言われると微妙なとこです(;^ω^)

前にこんなモデル設計しました

















userには共通項目があって、customer、employeeそれぞれの項目をもっています。

このプロジェクトでは、それぞれのテーブルをリレーションして実装しました

ふりかえって、parentオプションを使ってみます

userモデル typeカラムを追加
$ rails g model User first_name:string last_name:string \
       email:string company:string unit:string type:string

customerモデル
$ rails g model customer --parent user

employeeモデル
$ rails g model employee --parent user

userモデルはこんなの
class User < ActiveRecord::Base
end

customerモデルはこんなの
class Customer < User
end

employeeモデルはこんなの
class Employee < User
end

それぞれuserモデルを継承しています

では、employeeモデルにバリデーションを設定しましょう
class Employee < User
 validates :working_arrangements,
   presence: true
end

バリデーションの確認してみましょう






コールバックされましたヘ(^o^)ノ

customerモデルはどうでしょう?








saveできましたねー

userテーブル一つで、各モデルで振る舞いを変更できました

( ̄(エ) ̄)彡☆

Rubyのネームスペースヘ(^o^)ノ

Rubyはオープンクラスのメソッドをオーバライドできます。

いわゆるモンキーパッチ〜


便利だけど、すべての振る舞いを変更してしまうので危険(;^ω^)

では、自分で定義したクラスをネームスペースで囲ってみましょう

オーバライドされなくなりましたー

ネームスペースで囲ったときは、10行目のように使用することができますー

( ̄(エ) ̄)彡☆

2014年5月14日水曜日

Rubyのincludeとextendヘ(^o^)ノ

Rubyのincludeとextendの違いについて


つまりはこういうことです





















ポイントは32行目と38行目

ancestorsメソッドでご先祖さんを取得しています。

includeしたbarクラスは、barとfooが取得できていますが、
extendしたbuzクラスは、fooが取得できていません。

extendはクラスに定義されるのではなく、
selfの特異メソッドとして定義されるのですねー


間違えてたら教えてw

( ̄(エ) ̄)彡☆

参考
instance method Module#ancestors
instance method Object#singleton_methods
instance method Enumerable#grep
instance method Module#instance_methods


2014年5月10日土曜日

RubiniusでRubyを学ぶヘ(^o^)ノ

@merborneさんのProcを制する者がRubyを制す(嘘)rubiniusを知ったw

こいつはRubyの学習にはもってこいと思い、コードリーディングしてみたヘ(^o^)ノ

Arrayクラスのeachがどんな処理をしているのか調べてみる。

コードリーディングにunite-grepを使ってみる。

パターン検索にはagを使います(早いらしい???)

agのインストール
$ brew install ag

Vimプラグインのunite.vimvimproc.vimをインストール

unite-grepでagを使いたいので
.vimrc
" unite grep
let g:unite_enable_start_insert = 1
let g:unite_enable_ignore_case = 1
let g:unite_enable_smart_case = 1
nnoremap  ,g  :Unite grep:. -buffer-name=search-buffer
nnoremap  ,cg :Unite grep:. -buffer-name=search-buffer
nnoremap  ,r  :UniteResume search-buffer
if executable('ag')
  let g:unite_source_grep_command = 'ag'
  let g:unite_source_grep_default_opts = '--nogroup --nocolor --column'
  let g:unite_source_grep_recursive_opt = ''
endif

vimを開いて,gとたたくとこんな感じで検索パターンを入力できる






結果がuniteで表示される












kernel/bootstrap/array.rb:1:class Array ← Enterでファイルを開く

eachメソッドを見てみる













要素の数だけループして、ブロックに要素の値を渡してる

引数にブロックがないときはなんか返してる

to_enumとは

そんな時はctagsヘ(^o^)ノ

rubiniusのルートディレクトリで
$ ctags -R

さっきのto_enumで<C-]>定義先へ

定義先から戻る場合は<C-o>

( ̄(エ) ̄)彡☆


参考ページ
unite.vimの使い方まとめ
ackを捨てて、より高速なag(The Silver Searcher)に切り替えた