Bye Bye Moore

PoCソルジャーな零細事業主が作業メモを残すブログ

ruby

Mathライブラリとcase文をつかって、桁の接尾辞(kとかMとか)を出す

Math#log10について Math#log10は、その名の通り与えられた数値にlog10を適用した結果を出すメソッドです。 Math.log10(12_345_678) #>> 7.091514945509202 元の数値を3(=log10(1000))で割った結果を与えると…… (Math.log10(12_345_678) / 3) #>> 2.3638383…

Benchmark-IPSでRubyベンチマークを便利に使う

Benchmark-IPSはRuby標準添付のBenchmarkライブラリを便利に拡張してくれるGemです。 使い方 導入 $ gem install benchmark-ips 用例 普通のBenchmarkならbmメソッドを呼び出すところ、 ipsメソッドを呼び出すあたりが違います。 また、IPSならcompare!とい…

「BinData」で長さが不明の文字列を使いたい場合、count_bytes_remainingを使う

文字列の長さを指定してくれない不親切設計なパケット設計てありますよね。 そんな場合、count_bytes_remainingが使えます。 使い方 以下の例だと、末尾13文字を除いて途中の文字を:dataに放り込んでくれます # ... count_bytes_remaining :bytes_remainin…

Module#const_missingを使って、未定義な定数に対する動作を定義する

Module#const_missingは、未定義な定数を参照した際に呼び出されるメソッドです。 こんな感じで使います。 class Test1 def Test1.const_missing(name) mapping = { /^Func(\d+)$/ => :func } mapping.each_pair do |rgx, args| if rgx =~ name.to_s return …

「BinData」のArray型は連続する短いデータの取り扱い時に便利

「BinData」のArray型は連続する短いデータの取り扱い時に便利です。 使い方 16進数リテラルで渡す 16進数リテラルで渡します data = "\x03\x04\x05\x06\x07\x08\x09" これを読み込むと ary = BinData::Array.new(:type => :uint8, :read_until => :eof) ary…

Zlib::GzipReader/WriterとStringIOをつかってファイルを作らずGzip圧縮なデータを扱う

ZlibはRubyに標準添付さえている圧縮系ライブラリです。 普段はFileクラスと一緒に使ったりします。 これとStringIOと組み合わせると、ネットワーク上でも利用可能です。 実際のところ。 str = ""; (0..1000).each { str += (0x61 + rand(0x10)).chr } 0..10…

Rubyのバックスラッシュ記法8進数で0-7以外を使うと、バックスラッシュ記法16進数風にパースされる

今回の記事はかなりマニアック……というか、誤爆したときくらいしか使い道が無いですが 使い方 "\022" は8進数記法です。 比較すれば、このとおり。 "\022" == "\x12" #=> true 並べて使うこともできますし、 "\022\064" #=> "\x124" "\022" + "\064" #=> "\…

「BinData」Choice構文で、条件毎に構造を変える

BinDataのchoice構文を使うと、部分的に一致してるスクリプトも一本化できます 使い方 class EData < BinData::Record string :val_a, :length => 8 string :val_b, :length => 4 end class DData < BinData::Record uint8 :val_c rest :rest end class Pack…

「BinData」で文字列型に関するアレコレ

BinDataの文字列型は自由度が高く、うまく使いこなせば楽ができます。 つかいかた 長さを指定する 長さを指定するなら、lenghtをもたせます。 obj = BinData::String.new(:length => 6) obj.read("abcdefghij") obj #=> "abcdef" 不足はヌルうめ 文字が不足…

「BinData」で余計なデータを放り込んでおく箱が必要な場合、restを使う

流れてくるデータに対し、とりあえず放り込む箱が欲しいなんて時は、restが使えます。 つかいかた class D < BinData::Record string :a, :read_length => 10 rest :rest end という風に実装した場合 obj = D.read(Array('a'..'z').join) #>> {:a=>"abcdefgh…

「BinData」で階層構造なデータを定義する

あまりに情報がゴチャゴチャして可視性が悪くなった場合、 階層構造にするとなんとかなるケースもあります。 使い方 一つのクラスに記述 class SampleBase < BinData::Record uint8 :val_a struct :nested do uint8 :val_b uint8 :val_c end end とやれば sb…

「BinData」で可変長なフィールドを定義する際はread_lengthが使える

「BinData」で可変長なフィールドを定義する際はread_lengthやlambda式が使えます。 lambda class Hoge < BinData::Record endian :big uint8 :len, :value => lambda { data.length } string :data, :read_length => :len end と定義した場合、「data」フィ…

「BinData」でエンディアンが変わらない場合はendianオプションを使ってやれば楽ができる

エンディアンがBigかLittleかで固定されている場合、endianを設定してあげれば以降「be」だの「le」だのと付けなくてすみます。 そのため、 前回の内容は require 'bindata' class Sample < BinData::Record endian :big uint8 :val_a uint8 :val_b uint16 :…

Rubyでバイナリデータを格好良く扱うgem「BinData」が素晴らしすぎて膝から崩れ落ちた

0x1234567890abcdef とてな感じのバイナリデータがあったとします。*1 これを適正に振り分ける場合、どうしてますか? これまでの私だと、文字列のまんま val_a = "1234567890abcdef"[10].chr とやるなり、unpackで配列化して val_a = "ab".unpack("CC")[0].…

TZInfoでカントリーコードを扱う

前述のTZInfoは各種タイムゾーン情報を格納しています。 なので、カントリーコードもメソッドで一気に出力させることができます。 ap TZInfo::Country.all_codes, limit:true とやれば、 [ [ 0] "AD", [ 1] "AE", [ 2] "AF", [ 3] .. [245], [246] "ZA", [24…

「TZInfo」でタイムゾーンを扱う

メールを送ろうにも、現地が深夜だとレスが遅くてガッカリする事ありますよね。*1 Googleなら、「国名 時間」とやってあげると現地時間がでてきますが微妙に面倒です。 そんなときはタイムゾーンを使うgem、TZInfoを使ってちょっとしたスクリプトを書いてみ…

「docopt」を使えばgithubやherokuのCLIツールみたいなUIをドキュメント駆動開発で実装できる。

Julliaとか聞いたこともない珍しい言語もサポートdocopt/docopt.rb · GitHub と、Rubyも対応はしているのですが docopt has been confirmed to work with 1.8.7p370 and 1.9.3p194. If you have noticed it working (or not working) with an earlier versio…

gem「view_source_map」で、Render元のファイルをViewに表示する

view_source_mapはViewにRenderもとのContollerファイル名を記載してくれる便利Gemです 使い方 特になんの工夫もなく、rails sしてあげれば <p>test</p> てな感じで展開されます。 ソースをみると、Railtie自体に細工をする事でこの魔法が実現されているようです……

オンラインREPL「http://repl.it/」が魔界技術すぎて辛い

ちょっとJavaScriptで遊びたいなーと検索をかけたところ…… オンラインREPL「http://repl.it/」を発見しました 使えるものの一例 JavaScript以外にも、色んな言語が実装されています。 一通り遊んでみた範囲では、軽い動作検証程度であれば十分用は成すようで…

Railsのbundle installで突っ込んだgemの配置先をみる

Railsのbundle installで突っ込んだgemの配置先をみるには 「bundle show」です。 $ bundle show sass /Users/shuzo_kino/.anyenv/envs/rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/sass-3.4.13また、半端に入力しても $ bundle show sas 1 : sass 2 : s…

Rubyで状態遷移を実装できるGem「AASM」(その4_現在の状態を表示)

現在の状態を表示する場合、current_eventが使えます。例えば、指定のメソッド中で現状のイベント名を提示したい場合 class AASM_Sample include AASM aasm do #中略 event :sence, :after => :comment do transitions :from => :sleep, :to => :transmit en…

Rubyで状態遷移を実装できるGem「AASM」(その3_状態に入ったあとの動作を定義)

event :sence do after { p "sence"} transitions :from => :sleep, :to => :transmit end といった感じで、eventの中に記述します。 あるいは、 assmのブロック外に def comment puts "comment" endとしてあげた上で event :sence, :after => :comment do t…

Rubyで状態遷移を実装できるGem「AASM」(その2_未定義の動作)

AASMにて、定義していない順番で呼び出しをすると例外を返してきます。とはいえ、そのまま動作を止めたくない場合もあるわけで… そういった場合は aasm :whiny_transitions => false do # ... end とすることで、「false」を返すように指定できます。 以前の…

Rubyで状態遷移を実装できるGem「AASM」(その1_導入)

AASMはRubyで状態遷移を実装できるGemです。 導入 $ gem install aasm 使い方 クラスの中で呼び出すDSLになっています。 たとえば…次のような、シンプルな状態遷移図を実装する場合は require "aasm" class AASM_Sample include AASM aasm do state :sleep, …

SlimでHTMLエスケープをしない場合「==」

yieldなど、HTMLエスケープをしたくない場合は「==」で出力すればOKです - def hoge; '&!hoge'; end = hoge br == hoge これが、 &amp;!hoge<br />&!hoge と出力されます。 参考もと slim-template/slim · GitHub

Slimでタグを切り替えたい場合はDynamic Tagが便利

Slimでタグを切り替えたい場合はDynamic Tagが便利です。 これを使うと… たとえば特定のユーザにだけ表示したいinputタグ…なんてケースを実装するのが楽です。 実際のところ ruby: def nyu @flag ? {tag: 'p'} : {tag: 'b'} end - @flag = true *nyu NYU wit…

SlimのSplat attributes「*」で要素代入を楽にやる

Slimでタグにクラスをくっつける場合、配列やハッシュで渡す事ができます。 a.menu class="highlight" href="http://slim-lang.com/" Slim-lang.comとやれば、 <a class="menu highlight" href="http://slim-lang.com/">Slim-lang.com</a> と、よろしくコンバートしてくれます。ここで、Splat attributesという機能をつか…

slimで最初の数え上げ要素だけ特別な処理を加える

次のようなslim形式のテキストデータがあったとします。 $ cat hoge.txt ul li.first: a[href="/a"] A link - 10.times do |i| li: a[href="/#{i}"] #{i} link li.last: a[href="/B"] B linkこれをSlimのコンバータにかけると、 のように最初の要素だけA、数…

slimrbコマンドで軽くSlimを扱う

slimrbは公式が提供しているslimのパーサコマンドです。 ただ、別途redcarpetというマークダウンパーサのgemが必要なので 先に導入します。 $ gem install redcarpet つかいかた $ echo 'markdown: 123 456 * a * b ' | slimrb なんてことをやれば、 <p>123 456</p> <ul></ul>…

Ruby製OSX用通知ツールterminal-notifierが結構便利

terminal-notifierはRuby製OSX用通知ツールです。 導入 $ brew install terminal-notifierRubyの環境が入っている場合は $ gem install terminal-notifierでもいけます。 使い方 $ terminal-notifier -message 'Pop!'とやると、 のように右上に画面がポップ…