2014年5月31日土曜日

Rubyの無名クラスヘ(^o^)ノ

anonymous_class = Class.new(String) do
def hello(name)
"Hello, #{name}"
end
end
ex_class = anonymous_class.new
p ex_class.hello("murajun1978") # => murajun1978
p anonymous_class.name # => nil

Classクラスの引数にクラスを渡すと継承と同じことができる

これと同じ
class Foo < String; end

11行目でクラス名を取得してるけど、nilなので名無しです

ちゃんと名前を付けてあげましょう
Foo = anonymous_class
p anonymous_class.name # => Foo

親クラスを確認
p anonymous_class.superclass # => String
p Foo.superclass # => String

helloメソッドの有無を確認
p Foo.instance_methods.grep(/hello/) # => [:hello]


( ̄(エ) ̄)彡☆

2014年5月30日金曜日

Rubyのinstance_evalヘ(^o^)ノ

昔VBとかやってた。

withとかでこんな感じで書けた
with foo
  .foo_method
end

これをinstance_evalを使ってRubyでやってみようヘ(^o^)ノ

class Foo
def bar
:bar
end
def baz
:baz
end
end
barbaz = :barbaz
foo = Foo.new
foo.instance_eval do
p bar # => :bar
p baz # => :baz
p barbaz # => :barbaz
end

こんな感じでfooを省略できる
foo.bar
foo.baz

インスタンス変数とかを条件に
メソッドコールしたりできるから便利

さらに17行目みたいに、
スコープを越えてローカル変数にアクセスできるのも便利

( ̄(エ) ̄)彡☆

2014年5月26日月曜日

Shinosaka.rb #5を開催したよヘ(^o^)ノ #shinosakarb

Shinosaka.rb #5

今回で5回目!

そして、初めて淀川を渡らなかった。。。(;・∀・)

開催場所はクレオ大阪北

会場にちゃりで向かっていると。。。

ぎゃる、ぎゃる、ぎゃる、ぎゃる、ぎゃる



Shinosaka.rbはぎゃるがくる勉強会?(こない

なんか、イベントがあったらしくなにやら入りにくかったwww

今回はみんなでもくもくしましたーヘ(^o^)ノ

















和室だったから、こんなかんじー

















僕は改修業務中心なので、リファクタリングの知識を深める為にこいつをもくもく


すごく良いのだけれど、サンプルコードが見当たらない。。。

テストもない。。。

全部自分で書かないとイケないので、中級者向きかなー

まだ途中なので、後日ここに感想書きまする

 懇親会も17:30から23:00までΣ(゚д゚lll)


お疲れ様でした。

そして、楽しかった!

ちけん、画像いっぱいありがとm(__)m

参加してくれたみなさん、当日の成果はここにお願いします><

次回も参加してねー

( ̄(エ) ̄)彡☆


2014年5月24日土曜日

Rubyのmethod_missingで動的メソッドヘ(^o^)ノ

method_missingで動的メソッドを作ってみよー

method_missingって...そうあれ!よく怒られるやつw

そいつをオーバーライドして、動的メソッドを作るよ

こんな感じ
class Enemy
def initialize
@enemies = {}
end
def method_missing(method_name, *args)
enemy = method_name.to_s
if enemy =~ /=\z/
@enemies[enemy.chop] = args[0]
else
@enemise[enemy]
end
end
end
Enemy.new.instance_eval do
name = "アボ"
max_power = 1080000000
puts "name: #{name}" # => name: アボ
puts "max power: #{max_power}" # => max power: 1080000000
end
view raw enemy.rb hosted with ❤ by GitHub
例えば、17行目でmethod_missingの第1引数には「:name=」こんなハッシュが、
 第2引数には「アボ」って文字列が渡される。

参照する場合、19行目では第1引数には「:name」=のないハッシュが渡される。

その場合は、インスタンス変数のハッシュから値を取得する。

Rubyは楽しい!

ちなみにコードに出てくる「アボ」はこの子です




















Dragon Ball Wiki

戦闘力53万だけど、MAXは10億8千!


( ̄(エ) ̄)彡☆

参考
BasicObject#method_missing

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パターン書いてみました

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

こんな感じ

[1, 2, 3].select {|n| n == 2} # => [2]
[1, 2, 3].select &2.method(:==) # => [2]
view raw array_select.rb hosted with ❤ by GitHub

( ̄(エ) ̄)彡☆

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

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

こんな感じ
class Foo
private_class_method def self.common_method(*syms)
syms.each do |sym|
define_method sym do
puts sym
end
end
end
common_method :murajun, :murajun1978
end
Foo.new.murajun # => murajun
Foo.new.murajun1978 # => murajun1978


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

( ̄(エ) ̄)彡☆

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はオープンクラスのメソッドをオーバライドできます。

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

class String
def to_s
"murajun1978"
end
end
"Ruby".to_s # => "murajun1978"

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

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

module Murajun
class String
def to_s
"murajun1978"
end
end
end
"Ruby".to_s # => "Ruby"
Murajun::String.new.to_s # => "murajun1978"
オーバライドされなくなりましたー

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

( ̄(エ) ̄)彡☆

2014年5月14日水曜日

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

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

module Foo
def foo
:foo
end
end
class Bar
include Foo
def bar
:bar
end
end
class Buz
extend Foo
def buz
:buz
end
end
# Bar Instance methods
p Bar.new.class.instance_methods.grep(/bar|foo/) # => [:bar, :foo]
# Buz Instance methods
p Buz.new.class.instance_methods.grep(/buz|foo/) # => [:buz]
# Buz Class methods
p Buz.new.class.methods.grep(/foo|buz/) # => [:foo]
# a list of modules and classes
p Bar.ancestors # => [Bar, Foo, Object, Kernel, BasicObject]
# singleton methods
p Bar.singleton_methods # => []
# a list of modules and classes
p Buz.ancestors # => [Buz, Object, Kernel, BasicObject]
# singleton methods
p Buz.singleton_methods # => [:foo]
view raw ruby_obj.rb hosted with ❤ by GitHub

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





















ポイントは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)に切り替えた