no_picture

Hiroshima Ruby Conference 2016でしかもオープンデータデイなのでRDFの話をした

Hiroshima.rbとRuby Associationの共催でHiroshima Ruby Conferenceが開催されました。 この日はインターナショナルオープンデータデイでもありオープンデータに関する話をすることにした。 ということで、「Hiroshima.rbの情報をRDFでオープンでリンクなデータにしたんよ」という話をした。 プログラマとしての視点で、RDFについて知りたかったことはQiitaにまとめておきました。 RDFに関する雑な説明 - Qiita つづいて、RubyでRDFを作る方法をQiitaにまとめておきました。 RubyでRDFを構築してみる - Qiita そして、今回はHiroshima.rbのサイトにJSON-LDでエンコーディングして、埋め込みしました。 scriptタグを利用して埋め込みをしています。(詳細はHTMLをみてください) schemaには https://schema.org/ を利用してるのでGoogleが認識することができます。 RDFのライブラリを使えばウェブページを読み込みして、データを取り出すことが単にできるとおもいます。 RDFにするとデータをつなぐことができて分散データベースをつくることができるというわけです。 RDFはとても柔軟なフォーマットでRDFからいろんな形式をデータを生成できます。 ただし、柔軟性をを得たトレードオフとして処理効率が犠牲になります。 RDFのデータはクエリをつかって、表データのようにデータをとりだせるので、うまく使えばネットで情報を収集して、扱いやすい形式に落として別のシステムへ渡したりもできるとおもいます。 とまあ、今回はRDFについて調べて疑問点だったことを自分が知りたかったことベースにまとめたついでに実践してみたという話でした。 具体例として参考になると幸いです。

no_picture

最近のMacでRubyのビルドに失敗するなら brew unlink apple-gcc42とかしたらいいかもしれない

友人のMacでRubyのインストールに失敗するらしいということでログとかいろいろみせてもらった。 結果だけいうと $ brew unlink apple-gcc42 を実行してもらったらなおった。 もっと詳しく rbenv と ruby-build をつかっているっぽくてログファイルを渡してもらった。 ログは失敗したときにここにあるよ。的なのが端末にでているはずだ。 たぶん、/var/folders/XXXXXXXXXXXXXXXXXX/ruby-build.20141014143529.76588.logみたいな感じになっている。 それを詳しい人に渡してきくようにするといいと思う。 中身をみたら ./configure で失敗していたので config.log をみせてもらった。 そしたら configure:3064: result: x86_64-apple-darwin13.4.0 configure:3335: checking for gcc-4.2 configure:3351: found /usr/local/bin/gcc-4.2 configure:3362: result: gcc-4.2 となってて Target: i686-apple-darwin11 となってて ld: library not found for -lcrt1.10.6.o collect2: ld returned 1 exit status なってた。 ターゲットが x86_64-apple-darwin13 になってないのがなんか嫌だなと思いつつ、事例が「rbenvで ruby インストールエラー (OS X mavericks) - QA@IT」に似ているので、 sudo ln -sf /usr/bin/llvm-gcc-4.2 /usr/bin/gcc-4.2 で解決すること的なことが書いてあるけどなんか嫌だなぁってことで、そもそもなんで/usr/local/binにgcc-4.2があるねん、ということで ls -l /usr/local/bin

no_picture

RubyでFacebookのコメントに写真を投稿する

FacebookのGraph APIをさわった。コメントを自動でしたかったからだ。 RubyでFacebook Graph APIをたたくにはサードパーティなgemを使うのでいろいろい種類がある。今回はkoalaを使用した。 コメントに関するAPIの仕様はここに書いてある require 'kola' object_id = "OBJECT_ID" file_path = "FILE_PATH" oauth_access_token = "ACCESS_TOKEN" file = Koala::UploadableIO.new(file_path) graph = Koala::Facebook::API.new(oauth_access_token) graph.put_object(object_id,"comments", source: file) で、投稿できる。graph.put_comment というメソッドがあるが、ファイルがわたせない。コメントしたいだけならこれで充分。 object_id が必要になる。 てっとり早い方法はブラウザでコメントしたいポストを開いたらURLに書いてある数字がobject_idである。 画像はsourceに指定するが Koala::UploadableIOで開いておく。 またoauth_tokenが必要になる。 Graph API Explorer(アクセスにはログインしている必要がありそう)``から作成できる。たぶん1、2時間しかつかえないはず。(ちゃんと調べてない) 権限は user_photos publish_actions が最低必要で、書き込みする場所によって対応したものが必要。 user_status user_groups などなど。必要に応じて追加する。 user_photosをつけてなくて3時間ぐらい悩んだのはただの愚痴。 ついでにRestClientで送りつける場合の方法 require 'rest_client' url = "https://graph.facebook.com/v2.1/#{object_id}/comments?oauth_token=" + oauth_access_token RestClient.post(url, "source" => open("/Users/eiel/Desktop/hoge.png")) 参考文献 Ruby: How to post a file via HTTP as multipart/form-data? - Stack

no_picture

ActionView を単体で使ってみる

誰が興味があるのか謎ですが、ActionView を単体で使ってみようと思います。 意外にも Rails の仕組みとか見えてくるかもしれません。 Rails 4.1 ぐらいから ActionPack から独立した記憶があります。どうでしたっけ。 テンプレートを使いたい時には erb, haml, slim などを単体で利用すればいいのであまり使う機会はないかもしれません。 雑感では、 layout 機能を使いたい インスタンス変数で値にアクセスしたい Rails が提供するビューヘルパーを使いたい あたりがメリットかと思います。 この記事のために作成したコードはこちらにおいておきます。 補足の部分は読み飛ばせるように書いているつもりです。 利用したRailsのバージョンは 4.1.4 です。 1 Hello, world まずは使ってみます。 ActionView::Base.new.render(inline: 'Hello, World!') # => Hello, world ActionView::Base のインスタンスを作成し、renderメソッドを呼びだします。 コントローラでの render メソッドはどうやらこの render メソッドのようです。 (viewで使う render もこの render ですが…) 1の補足 ActionView::Base Rails を使ってる際に erb ファイルの中で self.class を確認したことはあるでしょうか? ちょっと確認してみましょう。 <%= self.class %> <%= self.class.superclass %> #<Class:0x007f82891092e0> ActionView::Base self は無名のクラスになっていますが、そのスーパークラスは ActiovView::Base です。 ビューは ActionView::Base のインスタンスのコンテキストで実行されるわけです。ビューコンテキストと呼んでいるようです。 また、このクラスにヘルパーをミックスインすることでヘルパーとして利用できるようになります。 デフォルトのHelperはすでに include されています。 > ActionView::Base.ancestors.map(&:to_s).grep(/Helper/) => ["ActionView::Helpers", "ActionView::Helpers::TranslationHelper", "ActionView::Helpers::RenderingHelper", "ActionView::Helpers::RecordTagHelper", "ActionView::Helpers::OutputSafetyHelper", "ActionView::Helpers::NumberHelper", "ActionView::Helpers::JavaScriptHelper", "ActionView::Helpers::FormOptionsHelper", "ActionView::Helpers::FormHelper", "ActionView::Helpers::FormTagHelper", "ActionView::Helpers::TextHelper", "ActionView::Helpers::DebugHelper", "ActionView::Helpers::DateHelper", "ActionView::Helpers::CsrfHelper", "ActionView::Helpers::ControllerHelper", "ActionView::Helpers::CacheHelper", "ActionView::Helpers::AtomFeedHelper", "ActionView::Helpers::AssetTagHelper", "ActionView::Helpers::AssetTagHelper::StylesheetTagHelpers", "ActionView::Helpers::AssetTagHelper::JavascriptTagHelpers", "ActionView::Helpers::SanitizeHelper", "ActionView::Helpers::ActiveModelHelper", "ActionView::Helpers::UrlHelper", "ActionView::Helpers::TagHelper", "ActionView::Helpers::CaptureHelper"] 2 インスタンス変数を使う Rails ではコントローラのインスタンス変数がビューの中で使えます。 普段はRailsが自動でやってくれていますが、自分でインスタンス変数を設定するには assign メソッドを使います。 view_context = ActionView::Base.new view_context.assign(name: 'eiel') view_context.render(inline: 'Hello, <%= @name %>') # => Hello, eiel @name が eiel に展開されています。 ActionView::Base のコンストラクタの第2引数に渡しても設定できます。 2の補足 ActionView::Rendering コントローラがビューコンテキストに対して assign メソッドを利用して、設定します。 これは ActionView::Rendering で行われます。 この ActionView::Rendering には ActionController::Base にミックスインされていて、コントローラがビューを設定する処理などが記述されているようです。 > ActionController::Base.ancestors.map(&:to_s).grep(/ActionView/) => ["ActionView::Layouts", "ActionView::Rendering", "ActionView::ViewPaths"] ActionController::Base には ActionView::Rendering がミックスインされています。 ちなみに assign するのに使う Hash は AbstractController::Rendering#view_assign で作成されています。 def view_assigns protected_vars = _protected_ivars variables = instance_variables variables.reject!

no_picture

CucumberとTurnipとSpinachと。

最近 spinach というライブラリがあることを知って Cucumber や Turnip と同じようなものだということはわかっていたのですが、ちゃんと調べてみることにした。 Cucumber Turnip Spinach 「きゅうり」と「かぶ」と「ほうれん草」ですね。 一応ざっくり解説しておくと ビヘイビア駆動開発 を実践するためのテスティングフレームワークです。 Gherkin という書式を利用して自然言語をならべて記述した文書を使い、自動テストとの結びつけができます。 動くことを確認することができる仕様書として使えます。 今回登場している3つのソフトウェアは Gherkin を使っている Cucumber がら派生したライブラリです。 Turnip は Cucumber から派生して、使いやすく改良したものです。 Spinach は Cucumber から機能を削減して見通しをよくしています。 Turnip Cucumber から派生して、Cucumber のイケてないところが修正されており、最近徐々に人気が出ているようです。 るびまで取り上げられているので知っている方も多いと思います。 また rspec コマンドから実行することになります。 Spinach Spinach は GitLab で利用されています。 Cucumber から強い機能が外されてます。 ステップから引数をうけとったり、シナリオテンプレートが廃止されていたり。 「重複を排除するための機能は Ruby のレイヤーでやらせてしまおう」という感じがしました また、Gherkin は独自のものが再実装されていて国際化がされてないので、Cucumberだとできることが一部できません。 When や Given などは、日本語で「前提」や「もし」とかけましたが、Spinach 日本語が使えません。 もうちょっと詳しく 例として Feature をひとつ作成してみました Feature: Cucumber と Turnip と Spinach ちょっと遊んでみる Scenario: 配列の作成 Given

no_picture

Sensu を少しだけ触ってみた

ちょっと前に Sensu を試した。 大したことは試してないのですが、日本語の情報もあまりないので試したことを記録しておこうと思う。 Sensu って? Nagios という統合監視ツールの置き換えを狙ったプロダクトのようで、Nagios のプラグインがそのまま使えます。 そもそも Nagios のプロトコルをそのまま使ってるようです。 同様のツールとして Zabbix などありますが、結構毛色が違うツールだということを今回わかりました。(Zabbix は試したことがありますが、Nagios は試したことがないです) Zabbix は全部入りみたいな感じで、これだけでなんでもできたりして、入門するには難しい感じです。 Nagios を利用する際にはグラフを書きたい場合は munin などを併用する人も多いようです。 munin は個人的に設定が楽なので、ちょろっとした時に利用します。 そんなわけで、「いまどきの Nagios」 である Sensu を試してみようという流れです。 まずインストールしてみる どんなものかピンと来ない場合はまず動かしてみるほうがいいです。 Sensu をインストールするのに chef や puppet が使えるように公式から sensu-chef や chef-puppet があり割と簡単にインストールできるようです。 手動でもそんなに難しいわけではなく ドキュメントを見ながらやればできると思います。 というわけで、今回は sensu-chef を試しました。 私が chef の初心者なので、その辺のメモも書いています。 sensu-chef の README.md をみるとやり方が書いてあります。 Vagrant をつかって動かすサンプルがあります。 $ git clone git@github.com:sensu/sensu-chef.git $ cd sensu-chef/examples $ gem install bundler $ bundle install

no_picture

S3を使って静的サイトの公開する奴をしてみた。自動化できるみたいで幸せだった。

AWS 楽しいですね。プログラミングできる領域が増加する楽しさがありますね。 なかなかAWSのマネージメントコンソールとお別れできない、AWS初心者です、こんばんは。 Amazon S3 の売り文句に静的サイトにするという話がよくあります。 ちょっとやってみたのですが、マネージメントコンソールでのポリシーの設定とかめんどくさい。 具体的にいうと、S3を使って静的サイトを公開する手順に記載されてる1番と2番と3番がめんどくさい。 Webサイト用にS3のバケットを設定する。 バケット内のファイルがアップロードした際、自動的に公開されるようバケットポリシーを追加する。 HTMLファイルをアップロードする。 S3のwebsite endpointにアクセスし、ウェブサイト が表示されることを確認する。 という手順を踏む。 1番はデフォルト設定だとそんなにめんどくさくない。 2番はコピペして修正しなきゃいけなくて少しめんどくさい。これはやらないと毎回アップしたオブジェクトを公開しないといけない。上書きしたとしても。 3番はいろんなツールがありそうな気がする。今回は気にしない。 4番はしゃーない。 というわけで、1番と2番を ruby の aws-sdk をつかってやってみた。 require 'aws-sdk' def s3_static_site(bucket_name) @hostname = bucket_name set_policy set_website end def set_policy bucket.policy = AWS::S3::Policy.from_json(policy_json) end def set_website bucket.configure_website do |cfg| cfg.index_document_suffix = 'index.html' cfg.error_document_key = 'error.html' end end def s3 region = ENV['AWS_REGION'] end_point = "s3-#{region}.amazonaws.com" @s3 ||= AWS::S3.new(s3_endpoint: end_point) end def bucket @bucket ||=

no_picture

Rubyのオプション変数というグローバル変数

Rails のソースコードを読んでいたら before = $-w $-w = false require 'action_dispatch/journey/parser' $-w = before https://github.com/rails/rails/blob/v4.0.2/actionpack/lib/action_dispatch/journey/router.rb#L6-L9 というのがあって $-w なんだろうと思って調べたら オプション変数というグローバル変数があるそうな。 どうやら -w が指定されているかどうかの判断に利用できる模様。 つまり、このコードは -w がついていたかどうかを保存しておいて requireをして -w をもとの状態にもどす ということをしているようです。 -w は verbose レベルを設定する機能ですが、 ActiveSupportに一時的に変更する機能があったような気がしつつも、調べてない。 もう少し詳しく こういうのは実際に試すのが大事だよね。 指定しない場合 $ ruby -e 'p $-w' false 指定する場合 $ ruby -w -e 'p $-w' true ちなみに -w は -W2 と等価らしいので、これも確認してみよう。 $ ruby -e 'p $-W' 1 $ ruby -w -e 'p $-W' 2

no_picture

Jekyll 使うときは exclude: vendor しとけって話らしい。

素のJekyll なんて使う人はあまりいないと思うけど一応書いておこう。 以前から jekyll build が失敗するっていう話をしてる人がいて自分の環境じゃ、おきてなかったんだけど、bundle install --path vendor/bundle してるのが原因だったらしい。 _config.yml に exclude: ['vendor'] するのがよいでしょう。 ついでに以下のような感じにした。 exclude: ['Gemfile','Gemfile.lock','Rakefile','vendor'] 具体的なコミットはこちら 素のJekyllから拡張してる場合は注意。 middleman などなどを使うことをおすすめしとこう。 自分が発見したネタじゃないけど記録しておいた。

no_picture

CodeClimate のカバレッジは SimpleCovの設定がしてあるところだとうまくいかない

CodeClimate で、課金して利用しているとカバレッジを取得する機能がある。 設定方法はここに書かれてる 中身は SimpleCov らしく SimpleCov の設定より先に書いていたらうまくうごかなかった。 仕方ないので削除してみたら、うまくうごきました。 SimpleCov のフォーマッタを差し替えているらしく、両方使いたい場合は、MultiFormatter を使えばよいらしい。 SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[ SimpleCov::Formatter::HTMLFormatter, CodeClimate::TestReporter::Formatter ] しかし、CodeClimate ではカバー率を表示するだけっぽいのであまり使いどころがない感じでした。

no_picture

流れるようにプログラミングしたい - 合同勉強会 in 大都会岡山 2013 Winter

合同勉強会 in 大都会岡山 -2013 Winter- でライトニングトークをしました。 合同勉強会という名前からわかるように各勉強会からいろんなスピーカーがやってきて、セッションをします。 私はHiroshima.rb・すごい広島・WEB TOUCH MEETING からやってきたという形でライトニングトークをしました。 「流れるようにプログラミングしたい」というタイトルです。 Ruby で読み書きしやすいプログラミングをしたときの問題点を紹介しつつ、Haskell の良いところを紹介するといった内容です。 内容も多かったのでかなりの早口で喋りました。 コードはこちらら Ruby で関数型の思考でプログラミングをすると自然と流れるようなコードになりますが、問題があり、データをすべて読み終えないとプログラムが実行されないという状態になります。 その例が flow.rb のプログラムです。 puts ARGF.each_line .map(&:to_i) # 数値に .map { |n| n * 5} # 5倍する .select { |n| n > 10 } # 10より大きいものだけに .first(5) # 最初の5つ Haskell を使用した場合は、そのまま書いてもこの問題はおきず、現時点で処理できる時点まで処理してくれています。 main = do getContents >>= ( return . take 5 . -- 最初の5個 filter (>10) . -- 10より大きいものだけに map (*5) . -- 5倍する map read .

no_picture

RubyKaja 2013 に選ばれたんだ

そういえば RubyKaja 2013 に選ばれました。 RubyKaja はコミュニティごとに選出されます。 選出したコミュニティはHiroshima.rbさんです。 「なぜ選ばれたのかわからない!!」なんてことはなく、コミュニティの会場準備係(言いだしっぺ)だからでしょう。 そんなわけで選出の際にあえて自分が選ばれにくい方法考えたのですが、見事に失敗しました。 ということで、2014年も RubyKaja の選出があるはずです。 私がやるべきことは、** RubyKaja に選ばれたい人を増やすということでしょう。** 盛り上げていこう。 2013年の Ruby Kaja はなんと RubyKaigi2013 で授賞式が行われました。 たくさんの Rubylist がいるなかで祝われます。(行けなかったので雰囲気はよく知らないし、岡山を除くと県外にほとんど知り合いがいないので私の紹介の時は静かだったという噂もありますが。) ちなみに、RubyKaigi 2013 は5月末にありました。なぜ今頃、私は記事を書いているのでしょうか。 答えはノベルティが届いたからです。 いやだってなんかないと実感湧かないし、記事だって書けないじゃん 刮目せよ。このカッコイイ扇子とカッコイイステッカーを! 扇子のほうのRubyKaja という文字が見えづらい…。 まあいいや、MacBook に貼りつけてみよう。 読みかけの「プログラマのためのSQL」が眩しいですね。 どうでしょうか、皆様。たぶん13枚しかないRubyKaja2013とかけなびシールです。 そう、今ここに「私だけの Mac子さんが今誕生した」 しばらくは扇子の自慢をすることで RubyKaja 2014 を盛り上げていきたいと思います。 あと RubyKaigi に行く方法も考えたい。 まとめ Ruby 盛り上げようぜ。 ちなみにわかると思いますが、ステッカーは乗せてるだけで、まだ貼ってない。

no_picture

広島Ruby勉強会 #035 に参加したり、喋ったりした。

広島Ruby勉強会 #035に参加してきました。 リンク貼っておいてあれですがGitHubのWikiのほうが情報が多いです。 さて、今回は3つスライドを作るという暴挙に出ました。ひとつひとつに時間を割けられないので、たくさん作るのはよくないと思いました。 Hiroshima.rb について Hiroshima.rb の説明もだんだん何をしていいのか忘れてきそうなので、誰か作れよ。ということで作りました。 現在の広島Ruby勉強会が大事にしていることも付け足しておきました。 Hiroshimarbについて from Tomohiko Himura 数学文章作法を取り上げていますが、情報発信をする上で **数学の文章でなくても** 参考になる部分があると思います。 または、「数学ガールの誕生」という本があって、これは結城浩さんの講演を本にしたものです。これもたくさん大事なことが書かれていておすすめです。 その場で結城浩さんがセッションしているかのように感じてしまう丁寧な作りの本です。 ちなみに、スライドにする前の原稿がGistにあります。 コンピュータをもっと使おう これは広島Ruby勉強会はやや難しいという意見が多いので、プログラミング初心者が気軽に聞ける話をしようと試みてみました。 何をやろうか悩んでるうちにどんどん対象者のレベルが下がってこんな形になりました。 コンピュータをもっと使おう from Tomohiko Himura 個人的には、「どんな人でも簡単なプログラミングをするような世界になると良いなぁ」と、思ってたので、その辺りを伝えてみました。 Ver 0.1 なのはブラッシュアップしてもうちょっとちゃんとした形にしたいという考えです。毎月バージョンアップしていきたい。 あまり時間をかけていないので、聞き手のことをしっかりと考えられてない感がまだまだあります。 もっと修行します。 つながりをゆるふわにしよう ActiveSupprt::Nnotifications Rails のソースコードをちょっとづつ読んでいるので、その成果発表を毎月やっています。 今回は AcitveSupport::Notifications を取り上げました。 つながりをゆるふわにしよう Active supprt notifications from Tomohiko Himura これもスライドにした原稿をGistに公開しています。スライドではかなり修正しているし、typoも結構あってなおさないといけないですが、まだなおしていない。 喋らなかったこともあるし、そもそもかなり早口で喋ったのでも再確認したい場合にどうぞ。 その他のセッション 今回はいつもより参加者が多くて19人でいつもより盛り上がりを見せていたと思います。 僕のテンションは暴走しないように低めでした。むしろ、低すぎた感。 RailsとAWSで業務システムを構築してみた Rails, AWS, CI モダンな開発手法を試しつつ、毎月どのような感じになっているか報告されてます。ナイスジョブ。 リリースが近いということで実務的な問題への対処が出てきていました。 capistrano ではまる人が多いのはそれだけドキュメントがそろってないってことだと、これを書いてる時に思いました。 気になった点はスライドのどこ部分を話してるか強調すると良いな、と思いました。 時代はMiddleman Jekyll や Octopress を試してそこから Middleman に移行したらすごくよかった。という話でした。 しかし、あえて厳しいことをいうと、どのあたりが他よりよかったのかよくわからなかった。ちゃんと聞いてなかっただけかもしれないけど。 jekyll と比べると

no_picture

ruby-end マイナーモード - emacs

ruby-end モードをいれました。 ruby で end を自動挿入してくれるマイナーモードです。 似たようなマイナーモードとしては ruby-elecric-mode があります。 この子は他にもいろいろ機能をもっています。end の補完も機能のひとつです。 個人的にはかなか挙動が使いづらく end の補完の処理だけ利用していました。 また、emacs24 では微妙な挙動をしたりするそうです。 - [参考: Emacs24 で ruby-electric的なruby-modeを実現するには - メモとか] ruby-end は end が挿入されるタイミングが心地良いので試してみています。 インストール epel でインストールできるので M-x package-install で ruby-end で入力でインストールできます。 参考: package.el - EmacsJP 普通は package.el で充分かと思いますが、私は el-get を利用してるので (el-get 'sync 'ruby-end) を設定ファイルに書いて評価しました。 関連 自分の el-get のワークフローについて整理する

no_picture

OSC 2013 HIROSHIMA に参加した。

OSC 2013 HIROSHIMA に参加しました。 200名以上の参加があったらしいです。正確な情報が待ちどおしいです。 私も実行委員会に所属したり(あんまり手伝えてなくてごめんなさい)、Hiroshima.rb の枠でライトリングトークをしたり、すごい広島 と Hiroshima.rb の展示ブースで説明をしたりしました。あと、ライトニングトーク&じゃんけん大会 でライトニングトークをしてきました。前日の DB 勉強会 を含めると計3セッションをするという状況になりました。 Hiroshima.rb 広島でRubyが流行らないのはどう考えても俺たちが悪い Hiroshima.rbの発表については wiki に整理してあります。 というわけで、僕は毎年前座を務めているので、「Hiroshima.rb の紹介」と「広島でRubyが流行しているか調べた」のでその話をしました。 本当は僕も成果発表したかったのですが、時間が足りそうにないので諦めました。 その他のHiroshima.rb の活動は wiki にもまとめています。興味があれば覗いてみてください。 スライドは以下の感じなのですが、実際に使ったものとは違う完全版になっています。 広島で Ruby が流行らないのはどう考えても俺たちが悪い from Tomohiko Himura セッションを見にきてくれた方は20人以上いたと思うのですが数えてないのでわかりません。 セッションの元ネタは私がモテないのはどう考えてもお前らが悪い!でした。 セッションにはどこにもこのネタは入れてないので注意してください。 勝手にみんなのセッションをざっくり感想書いてしまいます。 岡山のRuby勉強会 岡山勢 まこぴー の LT です。 僕が「広島」と「岡山」の比較をしたので岡山の状況について喋ってくれました。 本人はもっとネタをいれればよかったといってましたが、もちろんいれるとよかったですが、岡山勢の牽制としては充分なトークだったと思います。 YouTube動画の再生回数がわし…気になります!! (きゅふぃーん うちの OSC でしか使えない秘密兵器 にょほう(にょ砲) の LT です。 4分超過の打ち切り御免のLTなら死んでいた。 息子さんの支援により笑いだけでなく、癒しも追加されたため、圧倒的に一番人気な LT になりました。 しかし、一番アニメ色があるセッションになっていた気がするのは言ってはいけない。 PaaSで簡単 Railsアプリを公開しよう! ~もあぐれっしぶ~ & Rubyを体験しよう! 広島の基盤 たかた さんの LT です。 タイトル的にはもっともアニメ色の強いセッションですが、去年にひきつづきPaaSの紹介になりました。

no_picture

最近やった Ruby でのミス - rspec の expect で 空白に括弧

Ruby かいてて些細なミスでハマったことを書いておきます。その2。 describe 'Hoge' do it do expect ('hoge').to eq('hoge') end end expect ('hoge') のところの括弧の前にスペースが入っているのが問題です。 正しくは describe 'Hoge' do it do expect('hoge').to eq('hoge') end end 'hoge'にto というメソッドがない、というエラーが出るので気づくのですが + がないというエラーになっててハマった。 解説 expect('hoge').to eq('hoge') は expect('hoge').to(eq('hoge')) と等価です。 expect ('hoge').to eq('hoge') は expect('hoge'.to(eq('hoge'))) と等価です。 to は expect の戻り値に対して使うメソッドです。 空白をいれてしまうと、expect ではなく ‘hoge’ に対し to を呼んでしまいます。 関連記事 最近やった Ruby でのミス - カンマで改行

no_picture

ssh でポートフォワーディングしてブラウザで開くだけの gemを作った

flaun という gem つくって公開してみた。 インストールするには $ gem install flaun でできます。 何をするgemかというと ssh example.jp -L 8000:localhost:80 open http://localhost:8000/ のようなことをするだけの gem です。 ~/.flaun ファイルに設定を書いておくと flaun [target名] で該当サイトが開けます。 [target名] は ID みたいなものでどれを開くか指定するためのものです。 設定はRubyで作った DSL でかけます。 sample という target名の設定は以下のようになります。 port 8000 target :target do host 'example.jp' end はじめから http://localhost:8000/foobarr のようにディレクトリなどpathを指定したい場合は port 8000 target :target do host 'example.jp' path 'foobar' end のように書けます。 どんな時に使うの アクセス制限かけたいけど固定IPがない。BASIC認証はちょっと…。 そんな時は localhost からのみアクセスしたいサーバがあることがあります。 Apache だと以下のように書いてるページですね。 Order allow,deny Allow from localhost こうなるとサーバからアクセスしないと表示することができません。

no_picture

広島Ruby勉強会 #32 で 発表したこと - ActiveSupport, jenkins

広島Ruby勉強会 #032 で、紹介したこととか、喋ったこととかまとめときます。 広島Ruby勉強会の各発表は Github の Wiki に整理されてます。 Rails のソースコード読んでるので面白そうなメソッドを紹介する - ActiveSupport Core Ext すごい cron - Jenkins を試した 勉強会自体の感想は別のところに書きました。 Rails のソースコード読んでるので面白そうなメソッドを紹介する - ActiveSupport ここ最近はほぼ毎日 Rails のソースコードを読んで簡単にメモをとっています。います。 概ね毎日サボらずやれております。 この内容は railsdoc.eiel.info で垂れ流しています。 まずは、ActiveSupport から攻めています。特に Core Ext の部分を読んでいます。ということで、4月から6月の間に読んだものの中で、適当に抜粋して紹介しました。 内容はこちら その他には読んでいて気がついたことを残しています。 すごい cron - Jenkins を試した ローカルに Jenkins インストールして、これ cron の代わりに使えることに気づいたので、使用してみました。 その中で気づいたことや問題点についてお話をしました。 おまけで ruby 関連の Jenkins の Plugin についてわかったことを話しました。 すごい cron ? - Jenkins 試した from Tomohiko Himura 具体的な設定方法は まだ公開してないです。ごめんなさい。 また時間をとって書きたいと思います。 しかし、cron として使うにはメモリを食いすぎるので、Local

no_picture

最近やった Ruby でのミス - カンマで改行

Ruby かいてて些細なミスでハマったことを書いておきます。 goro = "gorogoro", hoge = "hogehoge" 1行目の最後に カンマ が入っているのがポイントです。 期待した結果は goro # => "gorogoro" hoge # => "hogehoge" です。 実際には goro # => ["gorogoro", "hogehoge"] hoge # => "hogehoge" となりました。 1行目の最後にある カンマ を削除すれば期待した結果になります。 このミスは hash で値を渡していたところを 代入に書き換えたときに発生しました。異常はテストコードのおかげで直ちに検知できました。(ちらちら) 解説 カンマのあとの改行なので、 式が完結していないので以下と等価です。 goro = "gorogoro", hoge = "hogehoge" 括弧をつけてわかりやすくします。 goro = ("gorogoro", (hoge = "hogehoge")) もうちょっとわかりやすくします。 hoge = "hogehoge" goro = "gorogoro", hoge hoge が上にきているのに注意してください。 もう必要ないと思いますが、以下と等価です。 hoge = "hogehoge" goro

no_picture

rbenv install したときに 一緒に bundler をインストールする

rbenv install したときに bundler ぐらい自動で入って欲しいですよね。 たぶん。今日、そういうツイートを見ました。 rbenv には hook という機能が用意されているのでこれを利用するとできます。 hook したときに呼ばれるスクリプトは以下の場所に配置できます。 ${RBENV_ROOT}/rbenv.d /usr/local/etc/rbenv.d /etc/rbenv.d /usr/lib/rbenv/hooks 環境変数 RBENV_HOOK_PATH を設定すると好きな場所に配置できます。 私はホームディレクトリにおきたいので指定しました。 export RBENV_HOOK_PATH="$HOME/.rbenv.d" 必要に応じて .zshenv や .bash_profile などに書き込みましょう。 以下、 .rbenv.d に設定したと仮定して話をします。 rbenv install 時 にhook するスクリプトは .rbenv.d/install におきます。 拡張子を bash にする必要があります。 .rbenv.d/install/install_bundler.bash というファイルを作成して、 #/bin/sh after_install 'RBENV_VERSION="$VERSION_NAME" gem install bundler' とかいておけばOKです。 $ rbenv hooks install で rbenv install で hook される script を確認することができます。 rbenv-hooksというリポジトリをつくったので、作るのがめんどくさい人は環境変数を設定して、clone してください。 $ git clone git://github.com/eiel/rbenv-hooks.git ~/.rbenv.d READMEかかなきゃ…。 もうちょっと詳しく after_install というのは ruby-buildの rbenv-install で定義されてる関数です。 同様の関数として before_install があります。 このへんは ruby-buildの独自機能のようです。 rbenv hooks 自体は rbenv の機能です。 rbenv の各コマンド実行後に実行したいスクリプトがあれば、同じ手法が使えます。 ただ、対応してないコマンドもあるようなので、使いたくなったら、適当に追記して pull request すればよいと思います。(たぶん) # Load plugin hooks.

no_picture

rbenv で Ruby の version を一時的に切り替え

rbenv で ruby の version を一時的に切り替えたい場合があります。 rbenv は名前のとおり環境変数で挙動を変更することができます。 RBENV_VERSION を設定しておけばそのRubyを実行をすることができます。 $ ruby -v ruby 2.0.0p0 (2013-02-24 revision 39474) [x86_64-darwin12.2.1] $ RBENV_VERSION=1.9.3-p0 ruby -v ruby 1.9.3p0 (2011-10-30 revision 33570) [x86_64-darwin12.3.0] ruby だけでなく gem や gem で installしたコマンドにも有効です。 おまけ rbenv local でそのプロジェクトで使用するRubyを設定できますが、.rbenv-versionというファイルを生成します。 まれに、生成したくない場合があります。 例えばホームディレクトリにいるときです。 広い範囲で影響がでます。 rbenv global を使えばいいという説もありますが、バックグラウンドで ruby の script が動いていると必要な gem がないということが起きることがあります。 そんなときは rbenv shellが使えます。 一時的に ruby の version を固定できます。 $ ruby -v ruby 2.0.0p0 (2013-02-24 revision 39474) [x86_64-darwin12.2.1] $

no_picture

Ruby で モナドを書いてみた。

ちょっと気分転換したかっただけで、反省している。(2015年4月11加筆修正) 記事を書く目的があったわけでも、何か確認したかったわけでもないけど、自分的に得るものがあったので、それを書いておきます。 Rubyでモナドをつくってみました。 ソースコード モナドってモノイドに名前が似ていることからわかるようにモノイド的な特性があるらしいです。 Wikipedia:モノイド 今回の話は、モナドだと簡単にモノイドが作れるという話のような気がする。 結合律 モノイドであれば結合律が成立します。 結合律をプログラミングに当てはめてみると func1(); func2(); func3(); という命令列があった場合 func1(); func2(); func3(); と func1(); func2(); func3(); は等価と言えるという話にできます。 違いがよくわからないので、別名をつけてまとめてみます。 funcX(); // funcX () { func1(); func2(); } func3(); func1(); funcY(); // funcY () { func2(); func3(); } どちらも同じように動きますよね。 セミコロンを演算子とみたててみます func1 ; func2 ; func3 最後のセミコロンはみにくいので削除しました。 (func1 ; func2) ; func3 == func1 ; (func2; func3) 単位元 単位元の存在 - 演算してもコンテキストが変化しない値が存在する プログラムでいえばセミコロンだけでかこまれていればそんな感じになりそうです。 func1; ; // あってもなくても変わらない func2; かけ算で考える

no_picture

Rails で ajax をちょっと実験するときに `render text:` すると コールバックしてこない。

サンプルコードがなくて申し訳ないです。 rails で ajax を使用とすると 一般的には jquery-ujs を利用します。 あるリンクをクリックする時に非同期に読込みたい場合は <%= link_to 'hoge', @user, class: user-link %> に対して、 remote: true を追加します。 <%= link_to 'hoge', @user, remote: ture, class: user-link %> といった感じになります。 あとはサーバからのレスポンスが返ってきた時の処理を書きましょう。 $(function () { $(document).on('ajax:success', '.user-link', function (ujs, content, status, xhr) { $('#user-info').html(content); }); }); 少し説明不足ですが、気にせず。 さて、ここで リンク先が未実装で手抜きして: class UsersController def show render text: 'hoge' end end と、さくっと実装しちゃうと さきほど実装した javascript の コールバックが呼ばれません。 めんどくさがらずに、 app/views/users/show.htmle.rb などを作成してあげましょう。 そんなこと滅多にないか…。

no_picture

Ruby の とあるクラスの実装がどこにあるかわからない時の方法 - コードリーディング

広島Ruby勉強会 のネタ探しをしていて、「実装見てなにか面白いネタないかなー。」 って時に使ったコマンドを紹介。 例は Method クラスの実装を探す。 まずは git でソースコードをとってきている場合。 $ git grep 'rb_define_class("Method"' proc.c: rb_cMethod = rb_define_class("Method", rb_cObject); git grep を使います。git grep はサクサクなのでメインの探索方法です。 Emacs上から使うとジャンプも楽チン。 「git リポジトリじゃねーよ」って時は ag を使います。 $ ag 'rb_define_class\("Method"' proc.c 2331: rb_cMethod = rb_define_class("Method", rb_cObject); こちらは行番号とかでます。 ( のエスケープがいります。 ag というのは the silver searcher のことです。こちらも emacs から使う helm-ag というのがあるのでオススメします。 使える正規表現も違うような気がするので凝ったことがしたいならこちらを。 rb_define_class というのは Ruby の C API で クラスオブジェクトを作成します。このあたりに メソッドをクラスに紐づける処理なんかがあったりします。 それでは Happy な ソースコードリーディングを。

no_picture

libv8 が コンパイルしたり、バイナリで入ったりで、気になったので少し調べた。

気になったというか、環境によって失敗すると言われてしまった。 libv8 は the ruby racecer のバックエンドです。 調べてみると、「libv8 はバイナリバージョンの gem」 と「ビルドするバージョンの gem」があるのですね。 バイナリバージョンは当然のようにアーキテクチャごとあるようです。 libv8のバージョン一覧 3.16.14.1 March 28, 2013 x86_64-darwin-10 3.16.14.1 March 28, 2013 3.16.14.1 March 28, 2013 x86_64-linux yanked 3.16.14.1 March 28, 2013 x86-linux yanked 3.16.14.0 March 28, 2013 3.15.11.1 January 8, 2013 yanked 3.15.11.0 January 8, 2013 x86_64-linux yanked 3.15.11.0 January 8, 2013 yanked 3.11.8.17 March 22, 2013 x86_64-linux 3.11.8.17 March 22, 2013 x86_64-darwin-12 3.11.8.17 March 22, 2013 x86-linux

no_picture

ActiveModelを利用してフォームを作成した時の型変換

対応するレコードがないフォームを使う場合、ActiveModelを使用することで、シンプルなビューを構築しつつ、処理はモデルにかけます。 しかし、ActiveModelのノウハウってあんまり落ちていません。 それなりに ActiveRecord に対する理解も必要で、難しいですね。 ハマったことなど共有していきたいと思います。 フォームからのデータは文字列ですが、ActiveRecord にはコラム自体には型があるため、型変換を自動的に行ってくれます。 これを無意識に使用していると ActiveModelではまります。 具体的には以下のテーブルがあったとします。 class CreateUsers < ActiveRecord::Migration def change create_table :users do |t| t.string :name t.integer :age t.boolean :is_person t.timestamps end end end 利用例を見てみましょう。 user = User.new(age: '20') user.age # => 20 user.age.class # => Fixnum user = User.new(is_person: "1") user.is_person # => true user.is_person.class # => TrueClass 文字列から作成しているけども、自動的に数値や、真偽値へと変換されています。 ActiveModel を使用する場合は以下のように実装しておくとよさそうです。 class User2 attr_reader :age, :is_person include ActiveRecord::ConnectionAdapters def initialize(attributes = {}) attributes.each do |key, value| send("#{key}=",value) end end def age=(age) @age = age.to_i end def is_person=(is_person) @is_person = Column.value_to_boolean(is_person) end end 代入する時に値を修正するのが インスタンス変数に直接アクセスした場合にも型が保証できて良いです。 「別に文字列でもいいよ。」なんてこともあると思いますが、 数値だとおもってうっかり使うと '20' * 3 -> '202020' となって欲しい 40とは大きく違います。 チェックボックスを利用すると "1" などなど、値として降ってきます。 特に 真偽値への変換ですが、とりあえずわからなかったので、自前でごまかしていたのですが、調べました。 ActiveRecord::ConnectionAdapters::Column にさままな型変換のメソッドが実装されています。 https://github.com/rails/rails/blob/v3.2.13/activerecord/lib/active_record/connection_adapters/column.rb その中の value_to_boolean を使用しました。 def value_to_boolean(value) if value.is_a?(String) && value.blank?

no_picture

iOS で Digest認証してみる。 - AFNetworking

iOS で Digest認証するコードを書きました。 サンプルコードの作成は頼まれて作成しただけです。 折角なので、簡単な説明を 記事にしておきます。 サンプルコードはこちら テストサーバ構築 まずは動作確認をできるようにしないといけないので Digest認証 をするためのウェブサーバがないと困ります。Ruby の rack を使いました。 Digest認証をするには Rack のミドルウェア Rack::Auth::Digest::MD5 を使用しました。 Digest認証は ハッシュ化アルゴリズムの選択できるようになっているので、ミドルウェアはこのような名前になっているようです。 Rackのソースコードみにいったら、最初気づかなくて困りました。 config.ru は以下のように書きました。 use Rack::Auth::Digest::MD5, "auth", '' do |username| "password" end run proc { [200, {'Content-Type' => 'text/html'}, ['hoge']] } use の第三引数は opaque となります。デフォルトでは nil で、設定しないと動きません。はまりました。 蛇足ですが、 use の仕組みをよくしらなかったのでソースコードをちら見しました。 lib/builder.rb に実装があります。 def use(middleware, *args, &block) if @map mapping, @map = @map, nil @use << proc { |app| generate_map app, mapping } end @use << proc { |app| middleware.new(app, *args, &block) } end @map が nil の場合は middleware.new する処理が割り込むだけですね。引数はまるまる渡しています。 use する時の引数は 使用するミドルウェア の initialize メソッドをみればよいことがわかります。 Digest認証の場合は (ソースコード) def initialize(app, realm=nil, opaque=nil, &authenticator) @passwords_hashed = nil if opaque.nil?

no_picture

広島Ruby勉強会 #30で Liquidの簡単な説明をした

広島Ruby勉強会 #030で Jekyl の中で使用されている テンプレートエンジン Liquid のざっくりとした説明をする LT しました。 大したネタもないし、そんなに凝ったこともしてないですが、公開しておきます。

no_picture

ruby-build の プルリクエスト バトル

ネタです。 最近もろもろな事情で Ruby がリリースされることが多かったですが、ruby-build の更新を待っていた人はどれくらいいるでしょうか。 みんな待ちきれなくて自分で ruby-build のレシピを書いたんではないでしょうか? そして「俺がと プル リクエストをおくるんだ!!」と燃えたのではないでしょうか? これを Ruby のリリースがあるたびに発生する ruby-bulild プルリクエストバトルだと勝手に想像して楽しんでいます。こんばんは。 僕の場合はだいたいなぜか rbenv のほうをみにいって、「まだ更新がないないなー」っておもってレシピをかくんですが、書いたあとに ruby-build だったと気づく馬鹿なことをしているだけだったりしますが 今日も Ruby 2.0 のリリース がありましたが、このプルリクエスト バトル の行方はどうなったのでしょうか。 https://github.com/sstephenson/ruby-build/pull/299 https://github.com/sstephenson/ruby-build/pull/301 同じ Issue を立てないように気をつけたいですね。 それと Ruby 20周年おめでとうございます。 ついでにレシピの書き方 ネタだけで終わるのもあれなので。 ~/.rbenv にインストールしている場合は ~/.rbenv/plugins/ruby-build/share/ruby-build/ にレシピが配置されています。 今回の 2.0 の場合は install_package "openssl-1.0.1e" "https://www.openssl.org/source/openssl-1.0.1e.tar.gz#66bf6f10f060d561929de96f9dfe5b8c" mac_openssl --if has_broken_mac_openssl install_package "ruby-2.0.0-p0" "ftp://ftp.ruby-lang.org/pub/ruby/2.0/ruby-2.0.0-p0.tar.gz#50d307c4dc9297ae59952527be4e755d" とか前のバージョンを参考にして書けばよいです。簡単ですね。 なんでこんなことかいたのか なんで push してないんだー。って怒られたので Ruby 2.0 リリース & 20 周年 おめでとー。とかそういう記事書きたいじゃないですか

no_picture

Active Supportの日付演算ってなかなか不思議。

昨日の記事がかなり反響がありまして、みなさまありがとうございます。 関連のある記事を書きたくなりますが、とりあえず、変わらず淡々とメモも残していきたいと思います。ゆるりとGithub入門記事も書きたいです。 ActiveSupportが拡張する日付操作はとても便利です。よく使います。でも、ちょっと黒魔術だなぁって思ったことがあったので紹介します。 Rubyでは日付や時刻クラスのインスタンスと数値が演算できます。 今から1ヶ月後の日付が知りたいのであれば、以下のように書けます。 1.month.since # => 2013-03-07 12:51:18 +0900 1.months.since # => 2013-03-07 12:51:18 +0900 複数形でも単数形でも。 特定の日付からでも同様のことがしたい場合は以下のようになります。 DateTime.new(2013).months_since 1 # => Fri, 01 Feb 2013 00:00:00 +0000 DateTime.new(2013) + 1.month # => Fri, 01 Feb 2013 00:00:00 +0000 有名な機能なので、ご存知の方も多いと思います。 別に、一日単位なら month メソッドとか使わなくてもできます。 DateTime.new(2013) + 1 # => Wed, 02 Jan 2013 00:00:00 +0000 DateTime.new(2013) + 1.day # => Wed, 02 Jan 2013 00:00:00 +0000 さて、本題。 monthだけでなくhourやday,secondなどもありますが、戻り値の型はすべてFixnumになっています。 1 などの数値もFixnumです。 Rubyで日付や時刻を表わすクラスは DateTime, Date, Time などありますが、演算をした場合は、レシーバによって変化します。 でも、monthやsecond メソッドを利用してから演算すると引数によって動作が変化します。どれも足すのはFixnumなのに。 というわけで、サンプルコード。 require 'active_support/all' datetime = DateTime.new 2013, 2, 7 date = Date.new 2013, 2, 7 time = Time.new 2013, 2, 7 datetime # => Thu, 07 Feb 2013 00:00:00 +0000 date # => Thu, 07 Feb 2013 time # => 2013-02-07 00:00:00 +0900 # レシーバによって動作が変わる (1) # 1日先に datetime + 1 # => Fri, 08 Feb 2013 00:00:00 +0000 # 1日先に date + 1 # => Fri, 08 Feb 2013 # 1秒先に time + 1 # => 2013-02-07 00:00:01 +0900 # これを防ぐには和をとるものを明示する (2) datetime + 1.days # => Fri, 08 Feb 2013 00:00:00 +0000 date + 1.days # => Fri, 08 Feb 2013 time + 1.days # => 2013-02-08 00:00:00 +0900 # 秒の場合 (3) datetime + 1.second # => Thu, 07 Feb 2013 00:00:01 +0000 date + 1.second # => 2013-02-07 00:00:01 +0900 time + 1.second # => 2013-02-07 00:00:01 +0900 # Class は どれも Fixnum なのです 1 # => 1 1.class # => Fixnum 1.days # => 1 day 1.days.class # => Fixnum 1.second # => 1 second 1.second.class # => Fixnum # (1) の場合のみレシーバによって動作が変化。動作的には自然だと思う。 # (2), (3) の場合は 引数に応じた動作に。 Dateは演算の結果、型が変化する。 # 使う分には使いやすい。 いいたいことはソースコードにもかいた!

no_picture

Rubyの拡張ライブラリをデバッグしてみた。

結論から言うと解決していないんだけど、学んだことをメモしておきます。 あらまし ruby-2.0.0-rc1 で debugger を動かしたかった。 ruby-2.0.0-rc1 だとコンパイルすらできない! 結果: コンパイルはできるようになったしとりあえず、うごくけどすぐ落ちる。テスト通らない。 https://github.com/eiel/debugger/tree/ruby-2.0/doc 拡張モジュールをコンパイルする方法 手順としては rake compile するだけでした。 手動でやりたい場合は * Makefileを生成する * make する Makefileするには ruby extconf.rb とします。カレントディレクトリに Makefile ができるので make します。 拡張モジュールはextディレクトリにソースコードがあり、rake compile すると libに共有ライブラリ(.so, .bundle, .dll)ができます。 gem にして installする方法 gem build *.gemspec して gemを作ってもいいけど、だいたい rake gem で作成できます。 pkg/ にファイルが生成されるので、gem intall pkg/*.gem でインストールします。 やったこととか make してエラーが出る部分を rubyのソースコードで git log -S して変更内容を確認してひたすら直す。 APIとか拡張されてると思いますが、その辺はわからないので無理。 gdb を使ってデバッグする方法 ruby hoge.rbなどでセグメンテーション違反などで落ちる場合は以下の方法でデバッグできます。 $ gdb rubyのバイナリを指定[~/.rbenv/versions/ruby-2.0.0-rc1/bin/ruby gdb> run hoge.rb 書いてて気づいたんだけど、lldb でデバッグするべきだった?

no_picture

@souda1025 に PythonでFizzBuzzとかしてみた に対抗しろって煽られたので。

@soudai1025 が書いたブログ記事にPythonでFizzBuzzとかしてみたというエントリーがあるのですが、Facebookでこういうコメントをみた。 多分、ひむひむが対抗してくるはず。 全力でお答えしましょう。 とりあえず、普通 FizzBuzz かくならこうかくだろう。 def fizzbuzz(number): if number % 15 == 0: # number % 5 == 0 and number % 3 == 0 return "FizzBuzz" elif number % 5 == 0: return "Buzz" elif number % 3 == 0: return "Fizz" else: return str(number) if __name__ == '__main__': number = int(raw_input("Please enter an integer: ")) print fizzbuzz(number) 数値を入れると 数値の文字列 か “Fizz” か “Buzz” か “FizzBuzz” を返す関数を用意するほうが柔軟性があり、わかりやすいです。 さて、もとのコードを確認していきましょう。 int = int(raw_input("Please enter an integer: ")) def do_fizz(int): if (int % 3) == 0: return 1 return 0 def do_buzz(int): if (int % 5) == 0: return 2 return 0 def do_answer(fizz, buzz): flag = fizz + buzz if flag == 0: print int #引数に居なくても外のintを参照出来る elif flag == 1: print "Fizz" elif flag == 2: print "Buzz" elif flag == 3: print "FizzBuzz" do_answer(do_fizz(int), do_buzz(int)) さて、気になる点をあげていこう。 do_answer 関数が外のスコープにアクセスしている。 よくわからないフラグ処理がされている。 do_answer の引数が意味不明。 関数が外のスコープにアクセスしている 関数が外のスコープにアクセスしてしまうとその関数だけみたときに他の部分を確認しないといけないのでよくない。 それぐらいなら引数を追加しましょう。 よくわからないフラグ処理がされている do_fizz と do_buzz が関数名から何をするのかさっぱりわからない。 do_fizz は 3で割り切れる場合 1 を返し、それ以外の場合は 0 を返す関数である do_buzz は 5で割り切れる場合 2 を返し、それ以外の場合は 0 を返す関数である ということはコードをよまなければわからない。ならば、関数の頭にコメントをかくか、そのような名前の関数にすべきだと思う。 do_ という接頭辞が着いている以上何かする関数だと想像するので、ここで print されているのであれば、まだ良いと思うけど, iPhoneで閲覧していたらこの命名のせいで混乱しました。 do_answer の引数が意味不明 fizz って何?

no_picture

ActiveRecord の has_many で生成されるメソッドってActiveRecord::Relationに変換できる配列なんですね。

タイトルのとおりなんですが、ArticleとComment とかあったりして、ちゃんと設定をしておくと article.comments とやると あるArticleに紐づいているCommentがとってこれる機能です。 まず、結論からいうと article.comments.to_sql とか article.comments.scoped とか article.comments.joinsとかできる!! ということです。 article.comments.create ってかける時点でうすうす思ってたんですが、これがわかっていると小回りがききます。返しているものが ActiveRecord::Relationのようなものです。classを確認すると Arrayって言われちゃいますが。 もうちょい深く 以下のクラスがあることを想定してみます。 class Article < ActiveRecord::Base has_many :comments end class Comment < ActiveRecord::Base belongs_to :artcile belongs_to :user end class User has_many :comment end さきほど紹介した技を紹介すると User.first かつ Article.first な Commentを探す場合、以下のように書けます a = Article.first u = User.first a.comments.merge(u.comments.scoped) すると、こんな SQLができます。 SELECT "comments".* FROM "comments" WHERE "comments"."article_id" = 1 AND "comments"."user_id" = 1 aとかuとかを引数な関数を用意するとウハウハな気がしてこないでしょうか。 joinだってできます。 a =

no_picture

Devise で email 変更する。

Railsの plugin で 認証を行なう devise という gem があります。 このユーザ認証で 実際にユーザにメールを送信して、登録を完了するという機能を提供するのに confirmable という機能があります。 このConfirmableという機能を使用していると管理者が ユーザのメールアドレスを変更してあげる必要がある場合、代えるときもメールがユーザに送信されます。これが便利なときもあったりテスト時にこまったりすることがあります。 devise :confirmable した モデルには skip_confirmation! skip_reconfirmation! というメソッドが追加されてるので、これらを呼び出すことで回避することができます。 ちなみに、これらのメソッドの中身をみると def skip_confirmation! self.confirmed_at = Time.now.utc end def skip_reconfirmation! @bypass_postpone = true end となってます。 confirmed_at に値がはいっていれば有効で、@bypass_postpone が true で メールの送信が回避できそうですね。このあたりの実装はversionによって変更される恐れがあるので直接利用するには注意が必要です。

no_picture

Rubyの 1.8 スタイルの Hash を 1.9 に書き換える

syntax_fix を使うと一瞬でした。 (defun query-replace-ruby-18-to-19-stayle-hash (&optional delimited start end) "Rubyの 1.8 スタイルの Hash を 1.9 から導入されたスタイルへ確認しながら変更する ネストした hashには対応していない" (interactive) (query-replace-regexp ":\\([^ ]+\\) => \\([^ ]+\\)" "\\1: \\2" delimited start end)) という正規表現を指定しただけの Emacs Lisp も書いたけどみなかったことにしてください。

no_picture

ActiveRecordで関連レコードの自動保存

ActiveRecordで has_one なんかで関連づけしている場合、関連モデルを保存しわすれる。 そもそも、関連してることをドメインロジック上からは隠蔽したい。そんなときは autosave オプションが使えます。 関連するモデルが Information の場合、 has_one :information, autosave: true となります。 informationで親のモデル IDを validate presence かけてたらはまったことも一応メモしておきます。

no_picture

read_attributeの存在を知らなかった、死にたい - rails

Railsの ActiveRecordで レコードの属性にアクセスする際は動的に生成されたメソッドを使いますが、そのようなメソッドを上書きしている場合、値に直接アクセスする必要があります。このような属性情報は @attributes に保存されています。 /lib/active_record/attribute_methods.rbに定義されてる attributes メソッドを経由してアクセスしていましたが、なんとなく @attributes へ直接アクセスするだけかとおもってたのですが、違ったようです。 def attributes attrs = {} attribute_names.each { |name| attrs[name] = read_attribute(name) } attrs end という定義になってました。 attribute_names は文字列で属性の一覧を返すので @attributesは 普通のHashでキーが文字列です。 もし email というの属性にアクセスしたい場合は attributes["email"] になります。 attributes[:email] ではアクセスすることができません。 しかし、 read_attributeは シンボルでも文字列でも使用することができて、 read_attribute :email でも read_attribute "email" のどちらでも良いみたいです。 ちなみにエイリアスがあって [] メソッドになります。なので self[:email] などでアクセスできます。pubilcメソッドです。 read_attribute があるということはも write_attribute もあります。 ついでにもう少し深追い read_attributeの実装もついでにおってみると def read_attribute(attr_name) self.class.type_cast_attribute(attr_name, @attributes, @attributes_cache) end となってました。クラスメソッドを経由するようです こいつも中身を追うと def type_cast_attribute(attr_name, attributes, cache = {}) #:nodoc: return unless attr_name attr_name = attr_name.to_s if generated_external_attribute_methods.method_defined?(attr_name) if attributes.has_key?(attr_name) || attr_name == 'id' generated_external_attribute_methods.send(attr_name, attributes[attr_name], attributes, cache, attr_name) end elsif !attribute_methods_generated?

no_picture

ViewSourceMap が地味に役に立つ

ViewSourceMapというのが地味に役に立ちそうなので導入してみた。 部分テンプレートを render して出力された前後にどの view をレンダーしたのかHTMLのコメントを挿入してくれる。 <!-- BEGIN app/views/users/_form.html.haml --> <form /> <!-- END app/views/users/_form.html.haml --> ついでに、partial以外のレイアウトとかメインのビューとかもついでに出力してみるのもありかなと思ったりもするけど、その辺は明確だし、時間ができたら fork してみよう ソースコードも短いしRails の plugin 的なものを作ってみたいときにも参考になりそうでした。 https://github.com/r7kamura/view_source_map

no_picture

ruby 2.0.0-preview2 をいれて rails起動してみた

ruby 2.0.0-preview2 が出てるのでビルドして rails を起動してみた。 $ uname -v Darwin Kernel Version 12.2.1: Thu Oct 18 16:32:48 PDT 2012; root:xnu-2050.20.9~2/RELEASE_X86_64 preview1のときと同様にopenSSLがついてこないので、OpenSSLを一緒にビルドするようにrbenvを修正しました。[https://github.com/eiel/ruby-build/tree/2.0.0-preview2-with_openssl] bundle instalの実行で ~/.rbenv/versions/2.0.0-preview2/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:45:in `require’: cannot load such file – rubygems/format (LoadError) と出てしまいますが rubygemsのライブラリ構成が変わっててbundlerが動かないだけみたいなので、 $ gem install bundler --version ">= 1.3.0.pre2" として 1.3 系の gem をいれました。 あとは普通に rails が起動できました。

no_picture

もっと楽ができた。bundle init で作成したプロジェクトの rake task

以前 勢いでhiroshimarbというgemを作った。反省する気なんてあんまりない。という記事で gem の リリースをする方法を書いたのですが、 bundle gem で作られた rake タスクも見てあげると良いかもしれません(rake releaseだと push しつつ tag も切ってくれたりする)。(via @sugamasao) https://twitter.com/sugamasao/status/268286597110312960 というコメントを頂いてました。 なので、調べました。 $ rake -T rake build # Build hiroshimarb-0.1.4.gem into the pkg directory rake install # Build and install hiroshimarb-0.1.4.gem into system gems rake release # Create tag v0.1.4 and build and push hiroshimarb-0.1.4.gem to Rubygems rake release で git でタグをつくりつつ、rubygems.org に uploadしてくれました。 生成したgemは pkg ディレクトリ内に保存されます。対した作業ではないですが、バージョンを入力する手間が省けて素敵ですね。 taskの中身は Rakefileが $ cat Rakefile (gi#!/usr/bin/env rake require "bundler/gem_tasks" ということで gem_task.rb をみてみましょう。 require 'bundler/gem_helper' Bundler::GemHelper.install_tasks Bundler::GemHelper.install_tasksが呼ばれてます。 def install_tasks(opts = {}) new(opts[:dir], opts[:name]).install end install_tasksはインスタンスを生成して installすることがわかります。 つづいて インスタンスを生成するので、initilaizeです。 Bundle::GemHelper#initializeでは gemspecを読み込んでいるようです。なんとなくしかみてません。 def initialize(base = nil, name = nil) Bundler.ui = UI::Shell.new @base = (base ||= Dir.pwd) gemspecs = name ?

no_picture

Mac で rbenv 使って ruby-2.0.0-preview1 インストールすると OpenSSLがうごかないのでなんとかしてみた

以前書いたruby-2.0.0をビルドしてみた on Rbenvの方法で build できるのですが Mac OSX でやると OpenSSLのバージョンが古いようで、 bundle install などが失敗してしまいます。 なので OpenSSLを一緒にインストールするようにパッチを書いてみました。 githubにupしてます。 上記の記事と同じ状況であれば以下の操作でインストールできます。 $ cd ~/.rbenv/plungin/ruby-build $ git remote add eiel git@github.com:eiel/ruby-build.git $ git remote update $ git checkout eiel/master -b eiel $ rbenv install 2.0.0-preview1 patchの内容ですが share/ruby-build/ にビルド時のルールを定義するファイルがあるのでそこに OpenSSL を追加しました。でもそのままだと失敗したので、configure のoptionを追加したり make のオプションを潰したりしてます。 homebrewを使った場合の情報はおちてるんですが Gentoo Prefix を使う身としては使わずになんとかしたかった。 参考文献 http://blog.takuyan.com/blog/2012/11/21/rbenv-install-2-0-0-preview1-and-openssl/ https://github.com/mxcl/homebrew/blob/master/Library/Formula/openssl.rb

no_picture

ActiveSupport::Concern - Railsのソースとか読みはじめた 2

ActiveSupport::Concern - Railsのソースとか読みはじめたの続きになるのですが、 @netwillnet さんに。 ActiveSupport::Concernはモジュールが少しだけ書きやすくなるというメリットよりも、複数のモジュール同士に依存関係があったときにモジュール内でその依存関係をうまく解消させられるところに真価があるのでは https://twitter.com/netwillnet/status/270150759335723008 と素敵な突っ込みを頂いたので、rdocとソースコードと睨めっこしてきました。 睨めっこした結果の結論を書きたいと思います。 というわけで A -> B -> C という依存性があるモジュールを考えます。A には B が必要で。 B には C が必要という意味です。 module C def c "c" end end module B include C def b "b" + c end end class A include B def a "a" + b end end A.new.a と実行すると "abc" と出力されます。 これと同じことをクラスメソッドで実現しようとしてみます。 module C2 def c "c" end end module B2 def b "b" +

no_picture

Rails 3.2.9 で default_scopeに設定してる条件が属性の初期値になるらしい

あるプロジェクトでrails 3.2.9 にアップデートしたら テストが失敗しまくる。そのひとつに ActiveRecordの default_scope を使ってる部分に問題があるとわかった。 どんなエラーかと言いますと。 NoMethodError: undefined method `to_i' for [1, 2, 3]:Array from activerecord-3.2.9/lib/active_record/connection_adapters/column.rb:178:in `value_to_integer' [1, 2, 3] とか即値すぎて わけがわからないよ という感じだったんですが、いろいろ調べると class User < ActiveRecord::Base default_scope proc { where(state_id: [1, 2, 3]]) } end というコードがあったときに User.new すると発生することがわかりました。 仕方ないので、 class User < ActiveRecord::Base scope :valid, proc { where(state_id: [1, 2, 3]]) } end として、ひたすら置換しまくりでした。 僕はdefault_scope使わない派なのであまり気にしない方向で。 ちなみに class User < ActiveRecord::Base default_scope proc { where(state_id: 1,name: "hoge") }

no_picture

Capybaraでtitleタグの内容が取得できなくなってしまった。

Capybaraを2.0にしたら動かなくなった Cucumber の step がありました。titleタグ のtextをとる部分。visible でない要素のtextは取得できなくなったんでしょうか。 コードを追う余裕がなかったので、Nokogiriで対処した。 target = find("title").text expect(target).to eq(title) を target = Nokogiri::HTML.parse(page.source).css("title").text expect(target).to eq(title) に書き換えました。 ちょっと無理矢理。 Cucumberについてやりとりする仲間がいないので、titleタグのテキストの中身なんて確認しなくていいよ!とか、そういうい話ができないのが寂しいですね。

no_picture

debugger-ruby_core_source に Ruby 1.9.3-p327 のヘッダ追加してみた

2012/11/17 追記 1.1.5がリリースされて基本的に以下の作業は不要です。 以下の記事は興味がある方だけどうぞ。 昨日になりますが、 Ruby 1.9.3-p327 のリリースがありました。早速インストールして開発環境で試してみてます。 前回のリリースのときもそうだったのですが、rbenv と ruby-build を使用していると、 debugger-linecache のインストールにこけてしまいます。この子をインストールするには ruby の ヘッダが必要になります。(他の環境でもなるかもしれませんけども) この gem は debbuger を利用している場合必要になります。 そのヘッダを提供する debbuger-ruby_core_source というgemがあるので、この子を git clone で取得してごにょごにょすればごまかせます。 前回はごにょごにょしたものがすでにあったので git clone して gem build gem install のコンボで済んだのですが、自分でやってみました。Pull Request も出してるのでそのうち gem が更新されるのでそんなに気にする必要はないかもしれません。 すぐにインストールしたい人向け とにかく、動かしたい人で debugger-ruby_core_source.gem が欲しい人むけ $ git@github.com:eiel/debugger-ruby_core_source.git $ gem build debugger-ruby_core_source.gemspec $ gem instll debugger-ruby_core_source-1.1.5.gem あとは bundle install などやりなおしましょう。 どうやって更新するか知りたい人向け READMEみればわかるのですが簡単に更新できます。 $ gem install archive-tar-minitar $ rake add_source VERSION=1.9.3-p327 add_source という rake task が用意されてるので簡単です。 この実行には archive-tar-minitar が必要になります。 bundler に対応されてないので直接いれました。 ネットワークみてみると対応されてるのがありましたが取り込まれてないようです。 あとは commit を作ればOKです。 最近の gem は gem を生成する際に git ls-tree の情報が使用されるので commit しないとハマります。 では happy programming !

no_picture

ruby-2.0.0をビルドしてみた on rbenv

Ruby 2.0.0 preview1 の話題をちらほら見かけますし、 heroku さんが対応したらしいので遊びのプロジェクトで使おうと思いまして、buildしてみました。 私は rbenv を git clone でインストールしていて、ruby-buildも git clone しています。 この場合以下の操作でビルドできます。 $ cd ~/.rbenv $ git pull $ cd ~/.rbenv/plugins/ruby-build $ git pull $ rbenv install 2.0.0-preview1 $ rbenv global 2.0.0-preview1 $ ruby -v ruby 2.0.0dev (2012-11-01 trunk 37411) [x86_64-darwin12.2.0] git だと更新も楽チンですね。rails プロジェクトでも試してみたり、新機能を試してみたりしたいと思います。 新機能については 下記のサイトとかにちょろちょろあるみたいです。 http://el.jibun.atmarkit.co.jp/rails/2012/11/ruby-20-8256.html https://speakerdeck.com/a_matsuda/ruby-2-dot-0-on-rails 自分で試したら記事にしたいと思います。

no_picture

勢いでhiroshimarbというgemを作った。反省する気なんてあんまりない。

あらまし 広島Ruby勉強会で Hiroshima.rbでなにか gem を作りたいですよね。という話を前からちょくちょくしてたので、勢いで作成してみた。実際は反省している。 gemを公開するといっても、何か機能がないと寂しいので、 $ hiroshimarb open とすることで、Hiroshima.rbのウェブサイト を表示するようにしてみました。 インストール方法は $ gem install hiroshimarb リポジトリはgithubにあります。 gemの作成方法 せっかくなので gem の作成方法というか 本gemを作るにあたって作業内容を書いておきます。 プログラムの作成 まずはプログラムをかくためにプロジェクトの雛形を作ります。 gemを作りやすい構成になっていると都合がよいです。 Bundlerの機能を使うと良い感じの雛形がつくれます。 $ bundle gem hiroshimarb そうするると hiroshimarb ディレクトリができますので、READMEや hirosihmarb.gemspec をかきかえます。gemspecの情報をもとにgemが作成されます。summaryやhomepage、 descriptionを書きかえたりしましょう。もちろん hiroshimarb の部分は自分の都合の良い名前にします。 あとは適当にプログラムを作成します。 binディレクトリにコマンドを作っておけばコマンドとしてインストールされます。 ローカルでためす。 *.gemspecをもとにgem を作成するには $ gem build hiroshimarb.gemspec とします。そうすると hiroshimarb-0.0.1.gemのようなファイルが作成されます。 あとは $ gem install ./hiroshimarb-*.gem とすればインストールできます。 rubygems.orgで公開する。 $ gem install hiroshimarb で、インストール可能にするために rubygems.orgにgemを登録します。 まずは、sign upをしてアカウントを作成します。作成がおわったら $ gem push ./hiroshimarb.*.gem で送信することできます。 メールアドレスとパスワードを入力して終了です。

no_picture

「私はRSpecでテストをこんな感じで書いてる」に少し便乗してみる

私はRSpecでテストをこんな感じで書いてるという良エントリがあったので少し便乗してみます。 まずは上記の記事を。 最終的なrspecについてですが、私の場合は以下のような感じにしてます。 といっても、前回もかいたように試行錯誤の毎日です。 # -*- coding: utf-8 -*- require_relative 'user' describe User do describe "#admin?" do subject { user.admin? } let(:user) { User.new(role: role) } context "管理者の場合" do let(:role) { 'admin' } it { should be_true } end context "一般ユーザの場合" do let(:role) { nil } it { should_not be_true } end end describe "#runnable_system?" do subject { user.runnable_system? } let(:user) { User.new(name: name) } context "管理者がリンディさんの場合" do let(:name) { 'Lindi' } before do user.stub!(admin?: true) end it { should be_true } end end end diffもつけておきます。 @@ -3,30 +3,34 @@ describe User do describe "#admin?" do + subject { user.admin?

no_picture

Pryでエイリアスを作成する

pry便利ですね。 edit-methodをよくつかいます。 ファイル開くためだけに使うときもあります。 だんだん、edit-methodってかくのがめんどくさくなってきたので、em あたりで利用したくなってきたので、やりかたを調べました。 Pry.config.commands.alias_command "em", "edit-method" こんな感じらしいです。第1引数が作成するエイリアス。第2引数が元のコマンドです。 pryの起動時の読み込みファイルは~/.pryrcなので、そこにかいてやればOKです。

no_picture

ActiveRecordで今のスコープをそのまま返したい

あるオプションパラメータがあるかどうかで、条件が変わるような処理を書いてると、オプションがない場合、ActiveRecord::Relationが欲しくなるような場面があります。 例えば @articles = Article @articles = @articles.where(valid: true) if params[:valid] みたいな感じになっちゃって@articles = Articleって何?な状態になります。 メソッド化しようとするとさらに困るのですが、scopedを使うと以下のように書けるようです。 @articels = Article.scoped @articles = @articles.where(valid: true) if params[:valid] なんか異臭がしなくなりましたね。 だから、どうした?って思う方もいるかもしれませんがメソッド化すると、 def self.valid(is_valid = nil) scoped.where(valid: true) if is_valid scoped end となります。scopedなしで書かこうとするとちょっと困ります。 そんだけ。

no_picture

ruby-debugからpryを起動する

Pry便利です。 スクリプト上で debugger をかいておくとそこでデバッガ(rdb)を起動できますが、debugger-pryをインストールしておくとpryコマンドが追加されてpryを起動できます。 Gemfileに書く場合は gem "debugger-pry", :require => "debugger/pry" 最近のRailsのGemfile {% gist 3051612 %}

no_picture

Rspecマッチャー rspec-html-matchersを試してみてる

Ruby on Railsで ViewやHelperの Specを書く際に利用するマッチャーに良いのがないか探してます。現在のRspecはcontainぐらいしかないので、細かくチェックしたい場合は若干使いづらいです。というわけで、rspec-html-matchersを試しています。 以前は rspec-tag_matchers を使用していたのですが、出力がちょっとイマイチでした。 Ruby Toolsでざらざらと探した結果、rspec-html-matchersを試してみることにしました。 Form用のマッチャーがいろいろあったり、内部に存在するタグをチェックしたりできるのが嬉しいですね。capybaraのhave_cssはsubject側で find(selector)しておく必要があるので、ややめんどくさいです。 いまのところの不満点は Hashで渡していくのがちょっと格好悪い 正規表現での属性チェックができなかった 暗黙的なsubjectを使用する場合、ブロックがあると不具合がでる 3番目なんですが、have_tag マッチャーにブロックを渡し場合 shouldメソッドのレシーバをかかないと、ブロック内へと処理が流れないようです。 subject { render } it do should have_tag("a") do # このブロック処理が走らない with_tag("b") end end のように書いてしまうと with_tag("b") の部分が動作しません。3行目を明示的に subject.shouldとすると動いてくれました。rspecの問題なのか、rspec-html-matchersの問題なのか切りわけが難しいのでとりあえず、我慢することにしました。 ブロックを渡さない場合は大丈夫です。 他は良好に使えています。 View Specの良い例が欲しいです。