zsh autoload

zsh使ってたけど、あんまりちゃんと使ってなくて、zshで/path-to-users-zsh.d/(site-)?functions みたいなとこに関数置いといて、autoloadするの、単にzshrc分割してsourceするのとどう違うのか知ってなかったけど、autoloadだと実行時まで中身を読み込まないからzshの起動が遅くならない、みたいなことが書いてあって、そりゃー便利だってなった。

会話のなかでモヒカンという言葉を使うのには特になにも感じないけど、オッサンが「おれモヒカンッじゃねっしー」とか「xxさんモヒカンッスよー」とか「モッヒー、やべモヒ」とか言い合ってるの見るの苦手でとてもつらい気持ちになる。特に言いたいことなし。

もう一個面白かったやつ

irb(main):007:0> require 'benchmark'
=> true
irb(main):008:0> require 'bigdecimal'
=> true
irb(main):009:0> n = 1000
=> 1000
irb(main):011:0> Benchmark.realtime { n.times { BigDecimal('3') == true } }
=> 0.023832
irb(main):010:0>  Benchmark.realtime { n.times { BigDecimal('3').is_a?(TrueClass) } }
=> 0.001259

https://github.com/rails/rails/commit/1fd78305b5812c186d9eed9475677f90946eba5f

シンボル

フト見たRailsのコミットログ https://github.com/rails/rails/commit/5d58948fe72e3b0422790b8adc0fab7bbf9e6573

to_symからto_s使うように変えてるけど、なぜだか一瞬分からなかった。シンボルがGCに回収されないから、入力値によっていくらでもシンボル増えるようなのはダメだ。ってことだろうということで落ち着いた。他の理由は特に思いつかなかった。

WebSocketからIRC繋げるやつ作った

今日Web Audioのハッカソンというかまあそんな感じのをしてて、音のなるIRC Client(on Browser)を作りたいと思って、そのクライアントを作るのを簡単にするために、WebSocketからIRC見たり、ポストしたり出来るようにしようと思って作った。Web Audioの会なのに、Audio関係するところまでいかずに終わってしまった。

https://github.com/ToQoz/ircmad

IRC <-> WebSoket Server(ここ作った) <-> WebSocket Client

こんな感じで立ち上げる

# proxy.rb
require 'ircmad'
Ircmad.new do
  set :host, '127.0.0.1'
  set :port, 6667
  set :channel_list, [ '#channel', '#channel2' ]
  set :username, 'username'
  set :password, 'password'  # 必要であれば
  set :websocket_port, 3333
end.run!
$ ruby proxy.rb

普通にonmessageにコールバック登録しておいたら、JSONが渡ってくるし、sendでJSON送ったら投稿できる。

var socket = new WebSocket('ws://localhost:3333')

// Send
socket.send(JSON.stringify({ channel: '#channel1', body: 'yeah' }))

// Get
socket.onmessage = function(msg) { console.log(msg.data) };
// => '{"username":"ToQoz","channel":"#channel1","body":"hello world"}'

ブラウザでIRCクライアントを作るとなるとちょっと面倒そうだけど、 こんな感じでWebSocketから扱えれば、簡単に作り放題だし、好きなの作れるかなと思った。

追記

サーバからの:PINGに対する PONG ってどーしてるんすか?

とのことですが、使用しているzirconというgemがやってくれています。 https://github.com/r7kamura/zircon/blob/master/lib/zircon.rb#L69

というかそもそもIRCとのやりとりは今のところ完全に任せっきりですね。

まあそれはともかくとして、IRC Server側が落ちた時とか長時間スリープした時(?)とかに微妙な感じなの、直したいと思っております。。

追記 v0.0.3

やりとりするjsonのフィールド名変えました。

at v0.0.3

var socket = new WebSocket('ws://localhost:3333')

// Send
socket.send(JSON.stringify({ to: '#channel1', body: 'yeah', type: 'privmsg' }))
socket.send(JSON.stringify({ type: 'join', to: '#ruby'}))

// Get
socket.onmessage = function(msg) { console.log(msg.data) };
// => '{"from":"ToQoz","to":"#channel1","body":"hello world","type":"privmsg"}'

// => {"from":"ToQoz","to":"#ruby","body":null,"type":"join"}
// => {"from":"hybrid7.debian.local","to":"ToQoz","body":"@","type":"353"}
// => {"from":"hybrid7.debian.local","to":"ToQoz","body":"#ruby","type":"366"}

あとreconnect的なのとかちょこちょこ入れた。

Devise and https

devise使ってて, ログインとか登録とかcontroller で force_sslとかして, https使うようにしてた場合、 大体普通に動くけどログアウトのリンクをプロトコル付きで生成するようにしとかないと、httpなページからログアウトしようとすると、DELETE http://example.com/users/sign_out 送って、そんなページないと怒られる。

-          <%= link_to destroy_user_session_path, :method => 'delete' do %>
+          <%= link_to destroy_user_session_url(:protocol => "https"), :method => 'delete' do %>

こんな感じで良さそう

Qiita Hackathonで作ったやつ

https://github.com/ToQoz/anything-hub

Introduction of anything-hub

$ anything-hub search:rails
$ anything-hub starred:ToQoz

みたいな感じでリポジトリ検索の結果やユーザーのスター一覧をanything風のインターフェースで絞り込んで選択肢ブラウザで表示するってやつ。

キャッシュするためだけのコマンドがあるので、

$ crontab -e
05 12 * * * /Users/toqoz/.rbenv/shims/anything-hub cache:search:rails >> /tmp/anything-hub.cron.log 2>> /tmp/anything-hub.cron.error.log
05 1 * * * /Users/toqoz/.rbenv/shims/anything-hub cache:starred:ToQoz >> /tmp/anything-hub.cron.log 2>> /tmp/anything-hub.cron.error.log

みたいな感じで定期的に実行するようにしておけば、実際使うときには比較的新しいキャッシュから高速に検索できる。

普通に使う分にはユーザー名だけ~/.anything-hubrcに書いておけば良くて(書き方はREADME.mdに書いてる)、一回目パスワード聞いて、そのユーザー名とパスワードからoauth tokenとって来てキャッシュしているが、キャッシュ消しちゃったときとかまたパスワード聞くプロンプト出たりするので、cronとか非対話環境で実行する場合は~/.anything-hubrcにtokenも書いておいたほうが良いと思う。tokenを取得するには$ anything-hub tokenってコマンドで取れるので、それを書いたら良い。

検索結果をanything風に絞り込んで選択はオマケ程度で、ユーザーのスターを検索できるのが便利だと思う。公式ではstarsはリポジトリ名ユーザー名からしか検索できないが、descriptionからも絞り込めるので、昔star押したと思う、よく覚えてないファイルアップロードのgemとかも、uploadとかで絞り込める。

OSX使ってないひと、というかOSXのopenコマンドみたいなのが違う名前の人は-s オプションにそのコマンド名渡せば良い。

ドメイン駆動とかそういうの、意図してないとしても言葉の節々から、「自分たちは顧客の業務への理解を高める必要があるが、顧客はシステムを分からないのはしょうがない」のような、虐げられる側が必死で頑張る姿勢みたいなもの感じて、とても辛く悲しくなってきて、結局頭に入らない。

pryの履歴からanythingっぽい感じで絞り込む

必要. 適当にgem installすれば良いと思う

~/.pryrc に追記

require 'ruby-anything'
def anything_hist(tail = 10)
  _anything_ command_result("hist --tail #{tail}").lines.map { |h|
    h.gsub(/^ *\d+: */, '').chomp
  }
end
$ pry
pry> anything_hist(50) | -> v { puts v; command_result(v) }
>>>> 履歴からanything インターフェースで選択して実行 >>>>

pry上で小さなパーツを組み合わせるみたいな環境を作りたかった

rubyのString/Symbol -> pryのcommand というのは 以前 http://toqoz.hateblo.jp/entry/2013/01/17/103458 に書いた。
pryのcommand -> rubyのブロック というにパイプを繋げたいと思ってpry-command_resultっていうのを作った。

Pryのコマンドっていうのは

pry> $ Pry.run_command

From: /Users/toqoz/.rbenv/versions/1.9.3-p327-perf/lib/ruby/gems/1.9.1/gems/pry-0.9.11.3/lib/pry/pry_class.rb @ line 232:
Owner: #<Class:Pry>
Visibility: public
Number of lines: 14

def self.run_command(command_string, options={})
  options = {    :context => TOPLEVEL_BINDING,
    :show_output => true,
    :output => Pry.output,
    :commands => Pry.commands
  }.merge!(options)

  output = options[:show_output] ? options[:output] : StringIO.new

  Pry.new(:output => output, :input => StringIO.new("#{command_string}\nexit-all\n"),
          :commands => options[:commands],
          :prompt => proc {""}, :hooks => Pry::Hooks.new).repl(options[:context])
end
=> nil

みたいな感じでnilが返されて再利用性がない。そこでそんな再利用するようなコマンドがないという話があるかも知れないが、それは再利用できない状況であるからそのようなコマンドしか生まれなかったみたいな感じなのではないかと個人的に思っている。pry-command_resultを使うとこんな感じになる。

pry> command_result('$ Pry.run_command')
=> "\nFrom: /Users/toqoz/.rbenv/versions/1.9.3-p327-perf/lib/ruby/gems/1.9.1/gems/pry-0.9.11.3/lib/pry/pry_class.rb @ line 232:\nOwner: #<Class:Pry>\nVisibility: public\nNumber of lines: 14\n\ndef self.run_command(command_string, options={})\n  options = {\n    :context => TOPLEVEL_BINDING,\n    :show_output => true,\n    :output => Pry.output,\n    :commands => Pry.commands\n  }.merge!(options)\n\n  output = options[:show_output] ? options[:output] : StringIO.new\n\n  Pry.new(:output => output, :input => StringIO.new(\"\#{command_string}\\nexit-all\\n\"),\n          :commands => options[:commands],\n          :prompt => proc {\"\"}, :hooks => Pry::Hooks.new).repl(options[:context])\nend\n"

整形して見たければ

pry> puts _
From: /Users/toqoz/.rbenv/versions/1.9.3-p327-perf/lib/ruby/gems/1.9.1/gems/pry-0.9.11.3/lib/pry/pry_class.rb @ line 232:
Owner: #<Class:Pry>
Visibility: public
Number of lines: 14

def self.run_command(command_string, options={})
  options = {    :context => TOPLEVEL_BINDING,
    :show_output => true,
    :output => Pry.output,
    :commands => Pry.commands
  }.merge!(options)

  output = options[:show_output] ? options[:output] : StringIO.new

  Pry.new(:output => output, :input => StringIO.new("#{command_string}\nexit-all\n"),
          :commands => options[:commands],
          :prompt => proc {""}, :hooks => Pry::Hooks.new).repl(options[:context])
end
=> nil

とすれば良い。

例えば Pry.run_commandがどこに書いてあるかだけ知りたいとき、pry-pipelineと組み合わせると、こう書ける。

pry> command_result('$ Pry.run_command') | -> v { v.lines.grep(/From/).join("\n") }
=> "From: /Users/toqoz/.rbenv/versions/1.9.3-p327-perf/lib/ruby/gems/1.9.1/gems/pry-0.9.11.3/lib/pry/pry_class.rb @ line 232:\n"

詳しくは - https://github.com/ToQoz/pry-command_result - https://github.com/ToQoz/pry-pipeline