PerlerのRuby日記

Rubyとか

privateメソッドはrespond_to?でfalse

タイトルどおり。一瞬詰まったのでメモ。privateなんだからオブジェクトは直接respondできません! class Foo def bar "bar" end private def baz "baz" end end foo = Foo.new foo.respond_to?(:bar) #=> true foo.respond_to?(:baz) #=> false

Rack::MethodOverrideを少しいじった話

よくある背景 よくある理由でIE対応を迫られて、ありがちな理由でPOSTなのにURLにパラメータがくっついてくるという ありふれた問題にぶつかったまでは良かったのだが(悪かったのだが) RESTfulなAPIに対応するという点で少しはまったのでメモ。 試したこと …

SinatraでJSONを返す

Sinatraと小さいAPIはとても相性がいい。 APIで返すものといえばJSONが最近は楽ですね。 まあ普通にrequire "json"して、#to_jsonすればよいのですが、 sinatra-contribにあるsinatra/jsonを使うのもよいかと思います。 Sinatraだけの場合 app.rb require "s…

Sinatraとsinatra-contribのStreamingの違い

Sinatra標準のStreamingと、公式拡張sinatra-contribのStreamingの違いについてメモ。 Sinatra標準Streaming 使い方 # coding: utf-8 require "sinatra" get '/' do stream do |out| out << "やあ<br>" sleep 1 out << "こんにちは、<br>" sleep 1 error_message = "…

なぜRackのResponse BodyはStringではなくArrayなのか

run lambda { |env| [ 200, {"Content-Type" => "text/plain"}, ["Hello World!"] ] } この3つ目のbody。 PSGIでもそうだけど、なんでStringでも良さそうなのにArrayなのか。 ふと気になってググったら全く同じ内容がstachoverflowにあった。 ruby - Why is …

Sequel4.1.0とmysql2でstream

Sequel4.1.0からmysql2クライアントのstreaming機能を使えるようになったらしい。 4.1.0.txt テーブルからでっかい行数を取得しようとするときに、 一気に取ってきてメモリに展開するのではなく ちょっとずつ取ってきて、メモリを節約できる。 例えば1行ず…

デフォルト引数を入れる変数を2個

デフォルト引数を入れる変数を2個 作ることもできると知ったのでメモ。 def hoge(foo = bar = 123) puts "foo: #{foo}" puts "bar: #{bar}" end hoge(234) #=> foo: 234 #=> bar: hoge #=> foo: 123 #=> bar: 123 引数を渡してhogeをcallしたときに、barの…

elsifに条件式がない

今日面白いコードを見た。 「elsif」に条件文がなくって、「あれ? これバグじゃね?」と思ったけど結果的にちゃんと動いていた。 a = "Hello, world!" if /hoge/ === a a.downcase! elsif a.upcase! end p a #=> "HELLO, WORLD!" こんな感じ。 たぶん「elsi…

ハッシュのシンボル

1.9からハッシュの生成に簡易な書き方ができるようになった。 {key:"value"} # => {:key=>"value"} JSっぽい。 ただ言語仕様上、値がシンボルの時は空けざるを得ないので、空ける。 「::」になるとクラスの空間セパレータになってしまうから。 { key: :value…

raiseで投げる例外クラス

raiseで投げる例外クラスは、Exceptionクラスを継承しなければならないみたい。 class Hoge end raise Hoge #=> TypeError: exception class/object expected

短いけどわかりにくいコードを可読性考えて書きなおしてみた

なんかこういう感じのコードがあったので、 def readable? !Hoge.count(self) == 0 && self.title != "" end こういう感じに書き換えた。 def readable? return false if Hoge.count(self) == 0 return false if self.title == "" true end 3行に増えたけど…

Sinatraでrake routes

SinatraでRailsのroutesタスクを作ってみた。 Sinatraのバージョンは 1.4.3 で確認。 見た目重視。 トップレベルにルーティングを定義している場合 Rakefile desc 'something like rake routes of Rails' task 'routes' do require "./app" Sinatra::Applica…

Sinatraについて

書く

RSpecのbeforeはeachよりallが先に動く

はまったのでメモ。 beforeがどこに書かれているかに関わらず、eachよりもallの方が先に動くらしい。 spec_helper.rb require "rspec" RSpec.configure do |config| config.before(:each) do puts "config before each" end end shared_context "sharecon" d…

三項演算子の代わりに

簡単に書けるならハッシュを使ってる。 slimテンプレート li class:"#{@sidebar==:home ?'active':nil}" home li class:"#{{home:'active'}[@sidebar]}" home @sidebarが:homeなら、 <li class="active"> になるし、 @sidebarが:home以外なら、ハッシュのキーが存在しないから、</li>…

cucumber-railsでpendingがCIで失敗扱いになった話

メモ。 cucumber-railsを入れて、 rails generate cucumber:install したときにできるconfig/cucumber.ymlが <% rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : "" rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] …

二次元配列は1回のeachで回せる

教えてもらったのでメモランダム。 いままで二次元配列は二回eachを使って取り出していたが、 ブロック引数に複数指定すると中の配列の要素がそのまま取り出せる。 いままでやってたやり方 array = [[1,2,3], [4,5,6], [7,8,9]] array.each do |ary| ary.eac…

Rails勉強会@東京 第80回に行ってきた

Rails勉強会@東京 第80回 - Rails勉強会@東京 | Doorkeeper 初めてのRails勉強会に行ってきた 入口の裏口に@onkさんと@nobyukiさんがいて戸惑うことなく入館できたよかった 自分含め5人で少ないなと思ってたら、結局そのまま5人だけだった やったこと まずdi…

変数とメソッドで同じ名前だと、呼び出しでは変数が優先される

hoge = 123 def hoge 234 end hoge #=> 123 # かっこをつけるとメソッドコール hoge() #=> 234

勉強会でGitの使い方について色々知った

Git

A-B-C-Dと積まれているコミットを A-B-C └D みたいに分けたいときどうするか branch && reset && commit -a それrebase --ontoでできね? マニュアル見よう! git help rebase We can get this using the following command: git rebase --onto master next …

シングルクオートをエスケープするだけの難解なお仕事

str = "hoge'fuga" puts str.gsub(/'/, "\\'") #=> hogefugafuga ??? 参考 http://qiita.com/items/7a1b98c0e36e7d4e33e2 http://yyuto.blogspot.jp/2009/06/ruby.html http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/14752 できました。 …

子クラスには定数も継承される

へぇと思ったのでメモ。 親クラスで定義された定数は、子クラスにも継承されて修飾なしで参照できる。 クラス名も定数なので、それも出る。 class Hoge ABC = 123 class Fuga end end class Foo < Hoge p constants #=> [:ABC, :Fuga] end なんだか変な感じ…

モジュールを継承したモジュールを作りたかった話

Hogeモジュールを継承したFugaモジュールを作ろうとしたらエラーになった。 module Hoge def self.hoge # 特異メソッド puts "hoge!!!" end end module Fuga < Hoge def self.hoge # 特異メソッド puts "fuga!!!" super end end Fuga.hoge SyntaxError: (irb…

evalよりinsntance_variable_setのほうが10倍速かった話

コンストラクタで、インスタンス変数を初期化する際に引数があればそれを、なければデフォルト値を入れたかった。 class Hoge attr_accessor :foo, :bar, :baz DEFAULT = { :foo => 'foo', :bar => 'baz', :baz => 'baz', } def initialize(opt = {}) DEFAUL…

クラスインスタンス変数

メタプログラミングRubyに書いてあったことメモ。 class Hoge ~ end の間に地の文で書かれている@の変数は「クラスインスタンス変数」と呼ばれるらしい。 class Hoge @p = 123 @@p = 234 end # クラスインスタンス変数 puts Hoge.instance_variable_get(:@p…

Proc.newとlambdaの違い

自分用まとめ。 結論 lambda使っておけば問題ない。 Kernel#procは? 1.8だとlambdaと同じ動きをする。 1.9だとProc.newと同じ動きをする。 使う必要ない。 違いその1 return lambda内でのreturnは、メソッドのdefと同じ動きをする。分かりやすい。 lambda …

Procとlambdaは[]でも呼び出せる

.callだけだと思ったらでも呼び出せるらしい。 http://www.ruby-doc.org/core-1.9.3/Proc.html -> { puts "lambda!" } #=> "lambda!" Proc.new { puts "Proc!" }[] #=> "Proc!" rspec/core.rbのrequireがそうなってて、見たときびびった。

includeだけでincludeとextendする方法

読んでます。 メタプログラミングRuby 作者: Paolo Perrotta,角征典 出版社/メーカー: アスキー・メディアワークス 発売日: 2010/08/28 メディア: 大型本 購入: 18人 クリック: 533回 この商品を含むブログ (120件) を見る その中でMerbを例に「クラス拡張ミ…

ローカル変数をスコープ内側へ

Perlだとこれは動く。 my $outer = 123; sub hoge { print "$outer\n"; } hoge(); #=> 123 Perlは内側への変数スコープは有効だからだ。 対してRubyは動かない。 outer = 123 def hoge puts outer end hoge() #=> NameError: undefined local variable or me…

XMLを解析してハッシュにするベンチマーク

XMLをハッシュにしたかったのだけれど、やり方がいろいろあるらしくって計測してみた。 NokogiriのXPath NokogiriのSAX REXMLのpull-perser REXMLのstream REXMLのSAX2 参考: http://d.hatena.ne.jp/tohtas/20091101/1257092607 http://d.hatena.ne.jp/wine…