まりぴよこのブログ

日々の日記。技術ネタでまとまりきってないものの記録、伝わる文章の書き方を練習とか。

Rubyのミミックメソッド

ミミックメソッド

メタプログラミングRuby

メタプログラミングRuby

メタプログラミングRubyを読んでて、初めて出会った単語。。「ミミックメソッド」・・何だろ〜コレ?? ・・から、今までチラホラ見ていた self について新しい気付きがあったのでメモメモ!

付録Aのよく使うイディオム、1つ目の項目で出ていた「ミミックメソッド

Rubyでよく出てくる、属性へのgetter,setterを使う時なんかに、あたかも「メソッド呼び出しっぽくない」メソッド呼び出しのことを指しているらしい。

コード的にはこんな感じ

class Book
  def title
    @title
  end
  def title=(val)
    @title = val
  end
end

注:初心者(ワシか!)向け注意点。

普通はこんな風に書かない。 attr_accessor を使えば、Rubyがやってくれる。

ref.xaio.jp

とまあ。。普通にRubyコード書いてる分にはわざわざ書かないんだけど、Ruby的にgetter, setter はこんなふうにメソッドとして定義しているわけです。

こいつらを使う時、普通は

book = Book.new
# セッター使ってみる
book.title = 'メタプログラミングRuby'
# ゲッター使ってみる
book.title # => "メタプログラミングRuby"

なんだけど、実際のメソッド呼び出し的に厳密に書くと

book = Book.new
book.title=('メタプログラミングRuby')
book.title()

になる。 同じことなのでクリーンにかける最初の方式をみんな使ってる。

こんな感じで、他言語(Javaとか)出身者からすると、「あ〜publicなtitle属性定義して、直アクセスしてるわけね〜」と思ってしまうのだが、実際はメソッド経由なわけだ。

「他の何かに擬態している」メソッドなので、ミミックメソッド、と呼ぶらしい。

なるほどなるほど。。 ここまではなんとなく他のRubyの本とかで文法勉強してた時に聞いたことある感。

属性の不具合

ここで注意!

class MyClass
  attr_accessor :my_attr

  def initialize_attributes
    my_attr = 10
  end
end

こう書いてしまうと予期せぬバグを生み出してしまう・・そうだ・・

最初全くピンとこず・・

実行すると、こんなんなっちゃう。。

obj = MyClass.new
obj.initialize_attributes
obj.my_attr # => nil

10どこ行ってん!!!(涙)

理由

原因は initialize_attributes でのコードが曖昧なこと。

Ruby的にはこのコードが

  1. ローカル変数 my_attr に代入
  2. ミミックメソッド my_attr=() の呼び出し

なのか、区別がつかない。

迷ったらRubyは1を採用するそうだ。(確かにそっちのほうが明確。2はより厳密な指定方法があるわけだし)

回避策

class MyClass
  attr_accessor :my_attr

  def initialize_attributes
    self.my_attr = 10
  end
end

ここでselfが登場!!

こうすると曖昧さがなくなり、ミミックメソッドの呼び出し!ということがRubyに伝わる。

なので、「カレントオブジェクトの属性に代入する時は、明示的に self を使うこと」が重要なのだ。

雑感

今までなんとなく、 カレントオブジェクトの属性に代入には必ず self 付いてるの、Ruby的なお約束かな〜とかぼんやりと思ってたけど、(まあ確かにお約束といえばお約束だが)裏にある意味をちゃんと理解するって大事!

いや〜なんかスッキリした!

最近のRails自習方法

最近の自習方法について。

  • RubyMine(試用中:17/30)
  • サンプルにしてるアプリをひたすらコードリーディング
  • 書籍
  • Web

RubyMineにしてみた

ずっとiTerm + MacVimで頑張ってたんだけど、コード内をうまくジャンプできない&Rails全然知らんのに補完が一切ないが辛いので、良い良いともてはやされているRubyMineを使ってみている。

現在使用期間中の17日目辺り。 途中一週間程夏休みでほとんどMac使う時間が無く、試用期間をちょっと無駄にしてしまった感・・ まだ全然ショートカットキーを覚えられていない・・・

かなり良い感じ♪

なんだけど、最近コード書くより読む方ばっかりなので、Navigation系の機能しか練習ができない。 書く方もやらないとな〜・・

会得した技

  • 定義元にジャンプ:Cmd+BまたはCmd+マウスクリック
  • 全体検索:Cmd+Shit+F
  • 賢い検索:Shift+Shfft
  • Rails server の起動 : Ctrl+R

賢い検索は、ファイル名とか、シンボルとか、クラス名とか指定なく全体を検索してくれる。 でもホントはファイル名で探したいとか明確なターゲットがある場合も多いので、そっちのショートカットも覚えたいんだけど・・(脳みそ容量が足りてない)

これから会得したい技

(ショートカットがうろ覚え)

  • Rake関連タスクの実行
  • Class, File, Symbolのターゲットを絞ってジャンプ
  • Model, View, Controllerの行き来

コードリーディング

Railsの機能やよく使われる実装パターンを読み解く。 キーワード自体知らないものがボコボコ出てくるので、調べながらほふく前進な感じ。。

ほふくながら大体全体を見通し終わったので、次のお題を探さしださなきゃな・・と検討中。

書籍

RailsによるアジャイルWebアプリケーション開発 第4版

RailsによるアジャイルWebアプリケーション開発 第4版

ちょっと古い本だけど・・・ 第Ⅲ部 Rails詳説 辺りから再度読み始め。。 というか買った頃にやった時は、前半のアプリ作るチュートリアルで終わってたので、再度・・ではない。。 すこしだけ全体像が見えてきたので、以前チラ見した時より大分スイスイ読める。

メタプログラミングRuby

メタプログラミングRuby

こっちも古い本だけど・・ 以前ノリで買った時は全く歯が立たず、そっと棚に戻した本に再チャレンジ w

月曜日:オブジェクトモデル、火曜日:メソッド辺りまでなんとか読めてる。 水曜日:ブロックで急に圧倒的な眠気に気圧され、進みが悪くなっている・・・

Web

Rails Best Practices - Rails Best Practices

まだあんまり読めてない。 今後(の自分)に期待・・

Railsの勉強でまとめ記事(Qiita投稿)

最近ブログ更新が滞ってたんだけど、勉強結果のまとめをQiitaに投稿したのでそのことについてグダグダを書いてみる。

学習結果まとめ1

qiita.com

最近勉強ネタ元になっているアプリをウンウン言いながらソースコードリーディングしてる途中に見つけた、素敵実装について書いてみた。

よくある、お問い合わせフォームみたいのの、確認画面を出すところのきれいな実現方法だったのでエッセンスを書き出してみた。

お問い合わせフォームって、入力する内容と、一旦確認画面に出す内容って、ほぼほぼ一緒(そりゃそうだ・・確認なんだから)で、コントローラーもビューもバラバラに書いてしまうと、いわゆるDRYじゃなくなっちゃうな〜と思うんだけど、それをRailsのvalidation や afterコールバックをうまく使って綺麗に書く方法について。

ココで使われていた validates_acceptance_of なんて、存在も知らんかったくらいなので、大変勉強になった。

ぐぐっても validates_acceptance_of は地味なのか、ちょっと古めの記事しかヒットせず。

Tips的に、この無名ブログよりQiitaのほうが相応しかろう!と思ってそっちに書いてみたら、1日で自分史上最高のストック数になり、ちょっとビビる。。 今までって、ブログやらQiitaに書いたことって、自分でかってに掘った穴に落ちて、もがいて・・やっと出れた〜ってのを書くことばっかりだったので、たまたま見つけた人様の素敵実装をまとめたら、どんどこストックされると・・なんかじんわりと罪悪感が・・・

でもこのストックスピードって、みんな「これは素敵実装!」って思うってことなんだろうな。 うーんさすが。

学習結果まとめ2

qiita.com

最近のRail勉強のおかげで、なんだかRails routesと仲良くなってきたような気がする。

ビューで routing path を使いたい時に、いつもノートを何ページも戻って見直してた自分的忘備録をQiitaに書いてみた。

やっぱ Rails Best Practices はすごいな〜

Rails Best Practices - Generate polymorphic url

Rails で JavaScript 管理をbowerにしてから、method: :delete が効かなくなって devise sign_out できなくなった

前回の記事で無事 bower 管理で上手くいっていると思っていたけど・・

前段階: RailsアプリのJS外部ライブラリをbower管理にして、CircleCIがFailして泣きそうになった件・・ - まりぴよこのブログ

devise で sign_out できない!

No route matches [GET] "/users/sign_out"

コレが発生。 以前は普通にサインアウト出来てた様な・・

いつの間にかサインアウトできない仕様にしてしまっていた;;

devise sign_outできないで検索するとこんな感じ・・

qiita.com

・・・まさしく・・なんだが、GETにする対応で良いのだろうか・・・ 普通に今までDELETE送れてたのに・・なんかこの対応じゃダメな気がする・・

解決の糸口

ちょっと古めの記事ですが、コレが解決の糸口に!

kaorumori.hatenadiary.com

JavaScriptを読み込むようにしたところ、以前のままで正常に動作するようになりました。

まさにコレじゃね!? 身に覚えあり・・・

app/aseets/javascripts/applicaton.js

読み込んでるjsはこんな状態だった。

//= require jquery
//= require bootstrap-tagsinput
//= require_tree .

最初に合ったやつから、 require jquery-ujs が消えてる(というか消した記憶あり)

bootstra-taginputをBowerfileに入れたら、自動でjqueryがそっちに入ったので、 application.jsをいじくって、その時一緒に消した気がする・・

戻します!

//= require jquery
//= jquery-ujs
//= require bootstrap-tagsinput
//= require_tree .

そんなファイルないので取り込めません!(そりゃそうだ)

Bowerfileに入れます!

asset 'bootstrap-tagsinput'
asset 'jquery-ujs'

インストール!

$ ./bin/rake bower:install

asset pipeline を確認

$ ./bin/rails c
> Rails.application.config.assets.paths

その他参考になったサイト

stackoverflow.com

jquery-ujs のハイフンをアンダースコアにしていて、インストール後にまだjs読み込めん!となったため、下記サイトのお世話に・・

qiita.com

RailsアプリのJS外部ライブラリをbower管理にして、CircleCIがFailして泣きそうになった件・・

久しぶりのブログ更新・・

最近がんばってRailsのアプリ課題を進めているので、ブログの更新が滞っています・・

途中見つけたTipsはQiitaに書いてるんだけど、今回のはまだ生煮えなのでブログの方に書いてみる。。

bower で JS のライブラリ管理

Railsのプロジェクトで、jsライブラリいれよ〜と思った時、zip ダウンロードして vendor/assets に手動コピー、展開・・って流れがイヤだな〜と思って、以前調べていた手順書を元に、Railsプロジェクト内のJSをbower管理にしてみた。

↓自らの軌跡が役立って嬉しい・・

qiita.com

Bowerfileこんな感じ

asset 'bootstrap-tagsinput'

bootstrap で良い感じにタグをスタイルしてくれるライブラリを入れてみた。 こいつと一緒にjQueryvendor/assets の方に入ったので、邪魔になるといかんと思いgemで入ってた方のjqueryを消す。

Gemfileこんな感じ

- gem 'jquery-rails'  # こっち消した
+ gem 'bower-rails'  # こっち追加した

これで bundle update./bin/rails g bower_rails:initialize で初期設定完了。

ローカルでは動いた・・問題はそのあと・・

ここまでは特にハマりポイントもなく、順調に進む。 (10ヶ月くらい前の自分が一度ハマった沼だからね・・)

ローカルでは動作したので、githubにプッシュ!

・・・したらCircleCIがコケた;;

うわぁん。。(そう、前回はgithub + CircleCIまでやってません)

こんなエラー

$ bundle exec rake assets:precompile

rake aborted!
Sprockets::FileNotFound: couldn't find file 'jquery' with type 'application/javascript'
/home/ubuntu/micro-sof/app/assets/javascripts/application.js:3

jQueryないって・・・いわれてる気がする・・・

circle.ymlの設定??

(結局関係なかった)

vendor/assets/bower_components 以下のファイルをリポジトリに突っ込んでなかったので、CircleCIでもnpmやらbowerやらの動作が必要なのでは・・・?と考え、インストールしてくれるであろう設定を付け加えてみた。。

付け足したのはpreのとこ。

circle.yml

 dependencies:
   pre:
    - npm install & npm install bower -g
   post:
     - bundle exec rake assets:precompile

しかし、解決せず;;

(ここまで関係なかったとこ)

解決策

ふと思い立って、 bower がインストールできなくても、 bower_components の読み込み終わってれば jQuery あるんじゃ・・?と

.gitignoreに付け加えてた、 bower_components 以下無視を削除して、大量のファイル達もコミット!

したら動きました・・・

node_componentsとか、それ系の「ダウンロード&インストールするだけ」のファイルは、git commitしない、ってうろ覚えてた記憶があるんだが・・・・

bower_components はコミットしといた方がいいのかな・・・?

とりあえず、解決!

この辺の疑問点とかもスッキリわかったら、Qiitaにちゃんとした記事書こっと。

追記(2016/04/05)

やっぱりcircle.ymlの指定だけで解決できた・・・

半年後別のプロジェクトで同じ問題にぶち当たる。 ローカル環境では動くけど、CircleCI上で動かすとテストがコケる;;

Failure/Error: #= require bootstrap-sass/assets/javascripts/bootstrap/alert
     
ActionView::Template::Error:
couldn't find file 'bootstrap-sass/assets/javascripts/bootstrap/alert' with type 'application/javascript'

このプロジェクトもbowerでjs系のライブラリを入れてて、 bootstrap/sass がないよってエラー

circle.ymlに

test:
  pre:
    - bower install

を追記したら普通にインストールしてくれた・・・

参考: Deploying Grunt and Bower from CircleCI to Heroku with Node.js | Sebastiaan Deckers

Railsでネストしたモデルの link_to method: :delete と form_for する方法

ネストしたモデル

  • blog has_meny entries
  • entry belongs_to blog

の状態で、entryを削除したい。

link_to :delete

(hamlです)

before

= link_to 'Destroy', entry, method: :delete, data: { confirm: 'Are you sure?' }

after

= link_to 'Destroy', [ @blog, entry ], method: :delete, data: { confirm: 'Are you sure?' }

参考

stackoverflow.com

form_for

before

= form_for(@entry) do |f|

after

= form_for [@blog, @entry] do |f|

参考

stackoverflow.com

どっちも配列で渡せばいい。

つながるWeb services

すごい・・世界はつながっている・・・!!!

何にどのくらい時間がかかっているのか、調べてみてる

毎度毎度見積もりと実測が激しくズレるので、最近真面目に時間を気にしてみている。。

そして使い出したのがToggle

作業項目を記入して、スタートボタンをクリックするだけ! (なぜか家のMaxで作業項目を入力すると、自動でタイマースタートする。会社のWinだとスタートボタンクリックまで待っている)

同じChromeなんだけど、微妙に動作が違う・・ 家のに慣れてしまうと、うっかりスタートボタン押し忘れるミスが頻発して悲しいことになる;;

ここ最近のワークフロー

会社のタスク管理はTrelloなんですが、ここんとこの自分のワークフローが

  • Trelloでカード、チェックリスト作る
  • 作業開始と共にToggleでタイマー開始
  • 作業終了でToggleのタイマー終了
  • Trelloのタスクをチェックする

だったんですが・・・

ちょいちょいToggleし忘れる・・

あと、Toggleったまま席を立ったり、帰っちゃったりする・・ (帰っちゃうと、Toggleが何時間もタイマーつけっぱ~だよ。とメールで教えてくれる。めっちゃ親切♪)

繋がった・・・!

Toggleの隅っこにちょいちょいお知らせが出てるんですね。。

Toggle画面の右端下に時々お知らせが出てる(あとプロ版使ってみない?とか)

f:id:mpiyok:20150617114955p:plain

なんか見慣れた文字が・・Trelloと連携すんの??

ポチると、Chrome extensionページに飛ばされる。。

chrome.google.com

言われるがままにインストールしてみたが、Chrome拡張の位置に赤いボタンが増えただけ・・あれ??と思ってたんですが。。

f:id:mpiyok:20150617120151p:plain

コレこのままボタン押すと、普通にタイマーが起動するだけ・・ (作業項目は「Chrome」ってなってる。。)

Trello連携なんだから、Trello見なさい!

Trello画面の方を更新してみたら・・ボタン増えてた!!(驚愕)

f:id:mpiyok:20150617115409p:plain

ボタン押すと、赤くなってタイマー開始! すげ~~ すげ~~~~

もちろんクリックしたタスクがタイマーの項目になります(当たり前 ww)

最近の大好き3サービスが繋がった

新しいワークフローは

  • 作業開始:TrelloでToggleボタンクリック
  • 作業終了:Trelloでチェックリストをチェック(complete)
  • Slack連携で勝手にプロジェクトのルームにお知らせが通知される

おおお。。

なんか・・自分なんにもやってないのに、ハンパない達成感・・ ww

いつかやってみたい・・

Chrome extensionページで、色んな連携プロジェクトのアイコンが表示されてて、すげ~すげ~と思った。。 よくよく見るとちゃっかりesaもいるやん!すごいな!

なぜこんな不思議なことが・・と思ったんだけど・・

github.com

連携したいサービスの人たちがプルリク送って拡張してってるんだ・・

すごい・・すごいな・・世界は広いな・・