privateなセッタメソッドはself.をつけて呼ばなければならない
Rubyのprivateなセッタメソッドについてメモ。
Rubyのprivateメソッドはレシーバを省略しないと呼べない仕様だけど、
末尾に「=」がつくセッタメソッドに限ってはself付きで呼ばないと動いてくれないようだ。
class Foo def foo bar=("bar=") # NG(ローカル変数代入扱いになる) self.bar=("self.bar=") # OK bar("bar") # OK self.bar("self.bar") # Error end private def bar(i) puts i end def bar=(i) puts i end end Foo.new.foo
self.bar= bar aaa.rb:7:in `foo': private method `bar' called for #<Foo:0x00007ff5e3930270> (NoMethodError) from aaa.rb:21:in `<main>'
Kernel.openにパイプを渡す
Ruby2.4.3のリリースに、Net::FTPの脆弱性の修正をした、というのを見た。
CVE-2017-17405: Net::FTP におけるコマンドインジェクションの脆弱性について
ローカルのファイルを開くために、それぞれ内部で Kernel#open を使用しています。しかし、もし localfile 引数がパイプ文字 "|" で開始されていた場合、パイプ文字以降に並べられたコマンドが実行されてしまいます。
module function Kernel.#open (Ruby 2.4.0)
ファイル名 file が `|' で始まる時には続く文字列をコマンドとして起動し、コマンドの標準入出力に対してパイプラインを生成します
ファイル名が "|-" である時、open は Ruby の子プロセス を生成し、その子プロセスとの間のパイプ(IOオブジェクト)を返します。(このときの動作は、IO.popen と同じです。File.open にはパイプラインを生成する機能はありません)。
ファイル名の代わりに、 "|" を先頭につけたものを渡せば、パイプとかforkとかできるらしい。そういえばPerlでもこんなのあったわ。
やってみたメモ
パイプから読み取り
foo.txt
aaaaaa bbbbbb cccccc
pipe_r.rb
io = Kernel.open("| cat foo.txt") # 愚直に3回呼ぶ #puts io.gets #puts io.gets #puts io.gets # 一気読みする #puts io.readlines # 一行ずつ読む io.each do |line| puts line end io.close
$ ruby pipe_r.rb aaaaaa bbbbbb cccccc
パイプへ書き込み
pipe_w.rb
io = Kernel.open("| cat", "w") io.puts("Yeeeees!") io.close
$ ruby pipe_w.rb Yeeeees!
forkしてやりとり (IO.#popenのマニュアルのサンプルそのまま)
fork.rb
io = Kernel.open("|-", "r+") if io # parent io.puts "foo" puts io.gets io.close else # child s = gets print "child output: " + s exit end
$ ruby fork.rb child output: foo
使う機会があるかはわからないが、一応まとめてみた。
Railsのconfig/routes.rbの書き方を冗長で自明にした
何をしたか
Railsのconfig/routes.rbの書き方にいい加減嫌気がさしたので単純を羅列する方法に変えた。
自分一人ならレールに乗るのもいいけど、複数人でさわるならわかりやすさ重視の方がいいとおもう。
変更前
Rails.application.routes.draw do root to: 'root#index' resources :books, except: [:destroy] do scope module: :books do resources :authors, only: [:index, :show] do resource :emails end end end end
変更後
Rails.application.routes.draw do root to: 'root#index' get 'books' => 'books#index' , as: :books get 'books/:id' => 'books#show' , as: :book post 'books' => 'books#create' patch 'books/:id' => 'books#update' get 'books/:book_id/authors' => 'books/authors#index', as: :book_authors get 'books/:book_id/authors/:id' => 'books/authors#show' , as: :book_author get 'books/:book_id/authors/:author_id/emails' => 'books/emails#show' , as: :book_author_emails post 'books/:book_id/authors/:author_id/emails' => 'books/emails#create' patch 'books/:book_id/authors/:author_id/emails' => 'books/emails#update' delete 'books/:book_id/authors/:author_id/emails' => 'books/emails#destroy' end
文字が多いとか縦に伸びるとかデメリットもないでもないけど、見ただけで分かるという点で、自分はこれでいいとおもった。