Bye Bye Moore

猫マンション建築の野望を胸に零細事業主として資本主義の荒波に漕ぎ出したアラサー男の技術メモ

ruby

Rubyのクラスを作る際に可変長の変数をもたせたい場合

久々にRubyのお話です。 クラスを作る際に可変長の変数をもたせたい場合は、空Hashのデフォ値を持った引数を設定しておきます。 こうすれば、Hashを渡してあげれば内容を参照できますし、駄目な値なら弾く事ができます。 実際のところ デバッグ情報なんかを…

鬼車の文字列集合オプションをつかって、alnumが日本語を拾う怪挙動を抑制する

鬼車の文字列集合オプションはascii、unicodeとマッチパターンを切り替えできます。 これを活かすと、alnumが日本語を拾うという、怪挙動を抑制する事ができます 実際のところ まず何もしない場合。almum……つまり0-9a-zA-Zだけにマッチすべきところ、 漢字も…

restfulなサービスにcurlでアクセスする

みんな大好きcURL。 最近、下位10%を弾くテストなんて話が話題になりましたが、アレでも使える話です。 ログイン curl -c cookie.txt -d "user=kaboom" -d "pass=password" "http://example.com/login" curl -b cookie.txt "http://exapmle.com/admin/get_da…

rbenv環境下でgem系に付随するツールが上手く動かないなら、.ruby-versionが悪さをしているかも……

今回もショーもない話ですが、結構ハマったのでメモpassengerには、諸々の設定を確認するツールがあります。 $ passenger-configところがぎっちょん、このツールが半端に認識されて上手く動きません。 sudoの権限でやってみろ等々のネットの指示を全部見ても…

livescriptの演算子を使って文字列や配列を操作

相変わらず頭がおかしいlivescriptさんは演算子まで使い倒して短文化を推し進めています。 知ってるとif-elseの構文がなくなったりするかも。 「*」オペレータ 常識的に考えれば、「*」オペレータは掛け算。 というわけで、まぁ次の挙動はなんとなく理解はで…

AWKっぽい操作をRubyの構文でやるCLIツール「gr8」 その7:grep

gr8のgrepメソッドはlazyでgrepコマンドとawkを合わせた挙動を同時に実行できます。 $ ls | gr8 'grep(/(.+)(\.png)$/) {|s| printf "cp %16s %16s", "#{$1}.png", "img/#{$1.upcase}.jpg"}' cp ceo.png img/CEO.jpg cp system_sol.png img/SYSTEM_SOL.jpg$ …

AWKっぽい操作をRubyの構文でやるCLIツール「gr8」 その6:ライブラリの読み込み

gr8でも、Ruby製ライブラリを読み込むことができます。 ライブラリを読み込むには-rオプションです。 今回はgems.rbてな感じの名前でactive_supportと、自作メソッドを取り込んだファイルを作成します。 ## $ cat gems.rb require 'active_support' require …

AWKっぽい操作をRubyの構文でやるCLIツール「gr8」 その5:クォテーション

出力結果にクォテーションを出したい場合、qメソッドか、qqメソッドをつかいます。 実際の所 qメソッド:シングルクォテーション $ cat data | gr8 -F "map{self[0].q}" 'Haruhi' 'Mikuru' 'Yuki' qqメソッド:ダブルクォーテーション $ cat data | gr8 -F "…

AWKっぽい操作をRubyの構文でやるCLIツール「gr8」 その4:-Fで分割文字を

Fオプションをつかうと、分割文字を指定できます。 実際の所 $ cat data Haruhi!100 Mikuru!80 Yuki!120てな形にした場合、「-F"!"」てな感じで指定してあげます。 selfに配列形式で格納されています。通常のRuby配列の通り、0始まりです。 $ cat data | gr…

AWKっぽい操作をRubyの構文でやるCLIツール「gr8」 その3:sumメソッドとavgメソッド

avgはカラムの平均を出すメソッドです。 $ cat data | grep -v "^$" | gr8 -C 2 'map(&:to_i).avg' 100.0この記法は、以下のようにショートカットができます。 $ cat data | grep -v "^$" | gr8 -C 2 'avg_i' 100.0平均があれば、合算のsumのあります。 $ ca…

AWKっぽい操作をRubyの構文でやるCLIツール「gr8」 その2:mapメソッド

gr8でのmapは1行分をselfとみなし、順繰りにぶん回すメソッドです。 gr8は内部的にRubyを使っているので……ブロックを渡す事も、&:でlambdaを渡す事ができます。 $ cat data | grep -v "^$" | gr8 -C 1 'map(&:downcase)' haruhi mikuru yuki実装はオリジナル…

AWKっぽい操作をRubyの構文でやるCLIツール「gr8」

「gr8」はAWKっぽい操作をRubyの構文でやるCLIツールです。 mapやinjectといったおなじみの記法が使えるので、awk脳になりきれてない私のような軟弱者にピッタリです。 導入 Rubyを導入していれば $ gem install gr8だけでいけます。 Ruby抜きでも $ curl -o…

Array#fillで新規や既存の配列を一定ルールで埋める

Array#fillで新規や既存の配列を一定ルールで埋める事ができます。 実際のところ 既存の配列に手を加える事もできます。 ただし、破壊的なメソッドなので注意してください [1,2,3].fill(0) #=> [0, 0, 0] ary = (:a..:z).to_a ary.fill(nil, 0..10) #=> [nil…

Array#values_atを使うと複雑な条件で抽出できる

実際のところ 0番目、2〜6番目を抽出するような場合を考えます。 ary = (:a..:z).to_a ((buf = []) << ary[0] << ary[2..6]).flatten #=> [:a, :c, :d, :e, :f, :g] ary = (:a..:z).to_a (:a..:z).to_a.values_at(0, 2..6) #=> [:a, :c, :d, :e, :f, :g]

世界の現在時刻をNokogiriを使って把握する

仕事柄、海外との取引が多いので先方の時間が知りたくなるケースが多々有ります。 今回は、Ruby製の優秀なパーサーNokogiriと世界の時間を調べるWEBサイトTimeAndDateを併用してアレコレしてみようと思います。とりあえず実験として $ curl http://www.timea…

Dateクラスでも順繰りの呼び出しが使える

Dateクラスにも、downtoメソッドがあるので カレンダーを出すだのといった用途で活用可能です。 Date.today.downto(Date.today.prev_month) {|i| puts "#{i.month}/#{i.day}"} #7/23 # ... #6/23 参考もと class Date (Ruby 2.2.0)

Dateライブラリで末日を指定する場合、日付を-1にすればよい

月の末尾を調べたい場合……ActiveSupportを使うのも手ですが、 実は標準添付のDateライブラリで普通に用を為します。 ためしに、2月の末日を調べてみると…… Date.new(2015,2,-1) #=> #<Date: 2015-02-28 ((2457082j,0s,0n),+0s,2299161j)> Date.new(2014,2,-1) #=> #<Date: 2014-02-28 ((2456717j,0s,0n),+0s,2299161j)> Date.new(2013,2,-1) #=> #</date:></date:>

正負を返すメソッドを記述する際の文化圏間の違いについて

ちょっと面白かったのでメモ。Ruby文化圏で正負を返すメソッドでは「?」で終わります。 一方、Lisp文化圏ではpで終わるようですつまり、「ゼロか否か」を判定する処理は Rubyでは 0.zero? #=> true Common LispやEmacs Lispでは (zerop 0) t となるわけです…

Structの拡張版OpenStructは要素の削除や追加ができる

OpenStructは標準添付ライブラリです。 基本はStructですがパラメータの追加や削除が可能です。 また、Structと同様にメソッドを追加する事もできます。 require 'ostruct' ab = OpenStruct.new ab.foo = 25 p ab.foo # => 25 ab.bar = 2 p ab.bar # => 2 p …

魔術めいた組み込み変数の可読性をあげる標準ライブラリ"English"

標準ライブラリ"English"を使うと、 Perl由来の魔術めいた組み込み変数の可読性をあげる事ができます。 例えば、次の二つは同じ意味です。 $LAST_MATCH_INFO $~ ライブラリを読む必要はありますが、 速度に決定的違いを出す訳でもないので積極的に使ってきま…

Structクラスの値をEnumratorでぶん回したい時はStruct#each_pairを使う

Structクラスの値をEnumratorでぶん回したい時はStruct#each_pairを使うとよいです。 挙動はHashと同じなので気にせず使えます。 Point = Struct.new(:x,:y) a = Point.new(20,22) a.each_pair {|k, v| puts "#{k.inspect} => #{v}"} #>> :x => 20 #>> :y =>…

三項演算子など使わずともOR演算子使えば済むケースがある

三項演算子など使わずともOR演算子使えば済むケースがあります。あらかじめ変数の実体を持たせておく必要がありますが、 以下のような感じで使えます。 mark = nil (mark || "") #>> "" これを使うと、 フラグが立っていた場合は所定の文字を、そうでない場…

injectやmapのブロックの中が複雑になってきたら、素直にメソッドチェイン式に改めた方がいいかも

たとえば、次のようなコードがあったとします。 result = data.inject([]) {|a,c| ((c.x) > 10) ? a << c.y : a } ブロックの中がグチャグチャしてますね。 こういう時は、素直に result2 = data.select {|e| e.x > 10}.map(&:y) その上、この形式ならlazyを…

Structにはメソッドを持たせる事ができる

Structクラスを継承してはいけない(戒め - Bye Bye Mooreshuzo-kino.hateblo.jp でシレッと書きましたが、Structにはメソッドを与える事ができます。これを使うと、 「そのクラス内でしか使わないけど、色々値の扱いが入り組んで面倒なデータ構造」を調子よ…

Kernel#Arrayという奇妙なメソッドの挙動について

Arrayに引数を取ると配列として返してくれる...けどto_aと挙動が違わない - Bye Bye Mooreshuzo-kino.hateblo.jp の続きです。まず、ArrayはKernelのメソッドでした。 Array.newのエイリアスとか、そういった類のものではありません。 公式では 引数を配列(A…

標準ライブラリ「set」で集合を扱う(その4)

まさか、このネタの続きを書く事になるとは思いませんでした…… Ruby標準添付ライブラリのSetは、集合を扱う際に便利な奴です。これ、実は重複データを取り扱う際に結構有用だったりするそうです。 実際のところ 配列で重複があるデータを取り扱う場合、私で…

数値オブジェクトも凍結されているので破壊的メソッドは適用できない

以前、こんな記事を書きました。<調査中>Integerにinstance_evalによるメソッド追加は不可能?? - Bye Bye Mooreshuzo-kino.hateblo.jpすると、 けんぼー (id:kemboorg)さんから、 instance_evalはオブジェクトの破壊的変更に当たるからではないでしょうか…

<=>メソッドはクラス比較にも使える

Rubinusのコードを見てたら発見したのでメモ。 通常、メソッドは比較に使うメソッドです。 これを異なるクラス間でつかった場合……nilを返します。 1 <=> "a" # >> nil 1 <=> (1..9) # >> nil この特性を生かして class Range include Enumerable #略 def cov…

Ruby標準モジュール"Forwardable"でコアクラスのオレオレ式改造をしてみる

Ruby標準モジュール"Forwardable"をつかうと、 移譲というテクニックが使えるようになります。 これを生かすと元あるコアクラスをオレオレ式に拡張して扱う事ができるわけです。 実際のところ Stringを土台とする String#upcase、String#nextは流用 String#d…

inject内部で条件付きな式を使う場合注意すること

inject内部で条件付きな式を使う場合、 かならず初期値*1を返すようにしないと エラーを吐きます。 実例を挙げると、 ary.inject("") {|ary, item| ary << item if item > 'e'; ary}といったように初期値を吐き出すようにしないといけません。 実際のところ …

Comparbleモジュールを組み込んで比較メソッドを楽に定義する

""メソッドを定義し、Comparbleモジュールを読み込むと、 "", ">="といったメソッドを追加することができます。 実際のところ 前のコードを改造して、以下のようにします。 require 'pp' class Rarity include(Comparable) attr_reader :rarity def initiali…

Comparebleを使って自前クラスにsortの挙動を実装する(その2)

大分間が空きましたが、Comparebleを使って自前クラスにsortの挙動を実装する - Bye Bye Mooreshuzo-kino.hateblo.jp の続きです。メソッドを定義すると、希望通りにソートしたり比較できたりするようになります。 #実際のところ カードのレア度でソートする…

一定値以下の値を固定値で返したい場合、配列とArray#maxでちょっと楽しく書くことができる

その発想がなかったのでメモ。一定値以下の値を固定値で返したい場合…… 例えば、値がマイナスの時、0にしたいというようなケースでは、 配列とArray#maxでちょっと楽しく書くことができます。Rubyだと ary = Array.new(10) {rand(0xf)} #=> [9, 4, 5, 6, 7,…

Integerにinstance_evalによるメソッド追加は不可能

お急ぎの方へ Integerをはじめ、数値オブジェクトはfreezeされて変更を受け付けません。 よって、instance_evalのような破壊的メソッドは適用不能となります 本文 Integerにinstance_evalによるメソッド追加は不可能らしい……という話の記録メモです。文字列…

String#internで文字列をシンボルに変換できる

String#internで文字列をシンボルに変換できます。 "ZZ".intern #=> :ZZ シンボルのまま演算するのが面倒な処理は 一旦文字列化して後でinternでシンボルに戻してあげるといった処理が可能となります。 たとえば、公式によればSynbol#nextは :ZZ.to_s.next.i…

配列をfreezeする時は、ちゃんと中身もfreezeしとく

配列をfreezeする場合は mapにfreezeメソッドを渡し中身を定数化 配列自体をfreezeし、本体も定数化 という手順を取ります。ためしに、最初の手順だけで止めると str_frozen = %w(foo bar buzz).map(&:freeze) #=> ["foo", "bar", "buzz"] str_frozen[0].fro…

リテラル系記述を何度も呼び出す場合はObject#freezeで定数化してしまうと幸せになれる

%wリテラルは微妙に遅い…? - Bye Bye Mooreshuzo-kino.hateblo.jp 以前書いたこの記事。速度面での改善を図りたい場合はObject#freezeで定数化してしまう方法が有効です。 一度定数にしてしまえば一々再生成しないのでGCにも速度にも優しくなります。 ため…

procのcurry化や部分適用とcase判定文との合わせ技で似た条件判定をスマートに書く

case文、便利ですよね。 フラグ管理なんかだと重宝します。 が、ちょっと複雑な事をやろうとすると そんな時はProcを渡してあげると良くなるかもしれません 実際のところ あまり適正な例では無いのですが…… ビットフィルタかけて、任意のビットが立ってるか…

EnumerableにProc渡すなら外で作ってからにしましょう

Enumrableにprocオブジェクトを渡すとメソッドを渡した時のように実行してくれます。 このとき、procオブジェクト自体は外に出すか、素直にブロックを使うようにしないと、かなり遅くなります。 実際のところ 0を渡すと「A:1」、5なら「F:6」という感じの文…

String#[substr]でパターンに一致する場合そのパターンを返す

一致していれば文字列を返し "hoge fuga"['hoge'] #=> "hoge" 一致しなければ、nilを返します "hoge fuga"['foo'] #=> nil つかいどころと性能比較 require 'benchmark/ips' Benchmark.ips do |x| x.report("['substr']") { "hoge fuga"["fuga"]} x.report("…

"string contains null byte (ArgumentError)"と出たら、ヌル文字が入ってるので消す

たとえば、シリアルポートから数値をゲットしようとすると hoge.rb:32:in `system': string contains null byte (ArgumentError) てな感じでエラーを吐いて止まる事があります。 ヌル文字は"/000"とにして認識されており、表示はされませんが文字列に格納さ…

Structクラスを継承してはいけない(戒め

以前書いたStructで構造体なデータを扱う - Bye Bye Mooreという記事で class Point < Struct.new(:x, :y) def +(other_object) Point.new(x + other_object.x, y + other_object.y) end end とか書いていました。 が、公式リファレンスには 無名クラスのサ…

Rubyで標準エラーに出力するにはSTDERR

Rubyで標準エラーに出力するにはSTDERR puts "stdout" STDERR.puts "stderr" 実際のところ $ ruby error.rb stdout stderr $ cat buff.txt stdout $ ruby error.rb > buff.txt stderr $ cat error.rb puts "stdout"

Gem「railroady」でモデルを図表化する

Railroadsはgraph bizを利用し Railsのモデル関係をグラフ化してくれるgemです つかいかた gemリストに group :development, :test do gem 'railroady' end …and then run the master rake task… としてbundleした上で、必要な時に rake diagram:allとやって…

ZigbeeパケットをRubyで送ってみる

Digiから XCTU Software - Digi International てなツールは出ているのですが。 LinuxのGUIなしで送信しないといけない等々、そういった事情に合わせたものです。幸いにして、API2にも対応したruby-xbeeというgemがあるのでこれを使ってみましょう。 gem ins…

caseによってビミョーに違うメソッドを呼び出している場合の別実装

たとえば、次のようなタイプと値を指定すると特定の処理をしてくれるメソッドがあったとします。 def sortMethod(type,val) case type when :name then val.upcase when :val then val.next end end sortMethod(:name, "name") #>> "NAME" sortMethod(:val, …

「Ruby-Graphviz」で図表を楽に作る

Ruby-Graphvizは名前の通りGraphizをRubyから扱う事ができるgemです。 導入法 Graphvizを導入した上で gem install graphviz……とやればいいのですが。 OS X環境ではうまい事読んでくれないらしく require 'rubygems' gem 'graphviz require 'graphviz' と、…

until修飾子でloop系構文が不要になるケースがある

until修飾子は後置きのifみたいな感じで使える構文です。 違いは、フラグが立つまで延々と読み続けてくれること。 StringIOやSerialPortみたいな読みに行く系ライブラリでは重宝します。 実際のところ たとえば、以前扱ったN進数リテラルが混在している文字…

StringIO#eachには、FSっぽい感じで文字列を切り分ける機能がある

SringIOは標準添付でありながら、あんまり使われる所を見かけないライブラリ*1です。 これは文字列にIOクラスの挙動を持たせる便利なものです。このクラスのうち、StringIO#eachはちょっと特別な挙動をします。 引数に切り分け文字を指定してあげると、それ…

Enumerable#any?は条件が一致するか判定する

単純に、何か入っているか確認する用途にも使えますし (1..9).map.any? #>> true あるいは、ブロックを渡して条件が一致するメソッドがあるか調べることも可能。 (1..9).map.any?(&:odd?) #>> true これを応用したメソッドが、例のactive_supportに実装され…