読者です 読者をやめる 読者になる 読者になる

ZIP中のファイル名の文字化け(Ruby編)

tmtms.hatenablog.com という記事を書きましたが、今回はRubyでZIPファイルを作る時の話を。 RubyでZIPファイルを作るには、rubyzip というライブラリを使います。 % gem install rubyzip 次のようにしてZIPにファイルを追加できます。 require 'zip' Zip::F…

大江戸Ruby会議06

大江戸Ruby会議06 #oedo06 に行ってきたので雑感など。 会場 @sora_h さん生誕20周年記念ということで、会場も「ソラシティカンファレンスセンター」という場所でした。 Docker時代の分散RSpec環境の作り方 speakerdeck.com RSpecの実行に時間が掛かってたの…

Ruby製のEmacsライクなテキストエディタTextbringer

大江戸Ruby会議06で前田さんがRubyでEmacsライクなエディタTextbringerを作ったという発表をしていました。 発表資料 https://github.com/shugo/oedo06/blob/master/textbringer.md ブログ https://shugo.net/jit/20170320.html 最初はEmacs上の何かでプレゼ…

Sequelのトランザクション内でタイムアウトするとCOMMITされてしまう

ちょっと前にハマったのでメモ。 Sequelでトランザクションを使う時は次のように transaction メソッドにブロックを渡します。 require 'sequel' require 'logger' db = Sequel.connect('mysql2://user:passwd@localhost/test') db.loggers = [Logger.new($s…

Ruby の Enumerable#sum

「最近のruby-core (2016年7月)」に次のような記述がありました。 Enumerable#sum というメソッドが追加されており、特定の場合(浮動小数点数の配列とか)には誤差が累積しないアルゴリズムが採用されています。 Ruby 2.4 に Enumerable#sum が追加されたのは…

Ruby の Timeout の仕組み

Ruby で長い時間掛かるかも知れない処理のタイムアウトを行うにはこんな感じにします。 require 'timeout' begin Timeout.timeout(3) do # 3秒でタイムアウト hoge # 何かの処理 end rescue Timeout::Error puts 'なげーよ' # タイムアウト発生時の処理 end …

Sequelの罠

Sequel の罠っぽい挙動にハマったのでメモ。 次のようなテーブル a, b, c, d がありまして、 mysql> select * from a; +------+ | id | +------+ | 1 | +------+ mysql> select * from b; +------+ | id | +------+ | 2 | +------+ mysql> select * from c; …

要素数ができるだけ均等になるように配列を分割する

例えば10個の要素を持つ配列があって、これを3つに分割したい時に、 a = [1,2,3,4,5,6,7,8,9,10] n = 3 m = Rational(a.size, n).ceil a.each_slice(m).to_a #=> [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10]] みたいにすると、3つには分割できるんですが、要素数…

Rubyで指定バイト数を超えない文字列の取得

文字エンコーディングにUTF-8を使用した場合、1文字は1バイト〜4バイトです。 ある文字列の先頭からn文字の文字列を取り出すには次のようにできます。 str = "本日は晴天なり" n = 3 str[0, n] #=> "本日は" 先頭からnバイトを超えない最大の文字列を取り出…

RubyからProtobufを使う

MySQL 5.7.12 から追加された X Protocol は Protobuf というのを使ってるらしいです。 Protobuf というのをそこで初めて知ったので、とりあえず Ruby から Protobuf を利用する方法を調べてみました。 Protobuf はデータ構造をバイト列にエンコードしたり、…

Ruby の文字列データの複製について

Ruby で String オブジェクトを複製しても、文字列データは複製されません。 data = "a"*10*1024*1024 system "grep ^VmSize /proc/#$$/status" t1 = Time.now a = [] 100.times do |i| a.push data.dup end t2 = Time.now system "grep ^VmSize /proc/#$$/s…

flock(LOCK_EX) で EBADF

ちょっとハマったのでメモ。 ファイルを flock() で排他的にロックするために次のようにすると成功します。 % ruby -e 'File.open("hoge").flock(File::LOCK_EX); puts "OK"' OK が、NFS 上で同じことをやると失敗します。 % ruby -e 'File.open("hoge").flo…

Crystal の名前付き引数は自然に書けてつらくない

これは「Ruby脳にはCrystalつらい Advent Calendar 2015」の25日目の記事です。 qiita.com Ruby の名前付き引数の例です。 def hoge(a, b=1, c: 2) p [a, b, c] end hoge(123) #=> [123, 1, 2] hoge(123, 456) #=> [123, 456, 2] hoge(123, c: 789) #=> [123…

Crystal はソースコードも Crystal でつらくない!

これは「Ruby脳にはCrystalつらい Advent Calendar 2015」の24日目の記事です。 qiita.com Crystal のソースコードは Crystal で記述されています。最初は Ruby で書かれていたようですが、現在はすべて Crystal で書かれています。 Ruby は本体と組み込みラ…

Crystal はブロックがエラーになることがあってつらい

これは「Ruby脳にはCrystalつらい Advent Calendar 2015」の23日目の記事です。 qiita.com メソッドに渡されたブロックを実行するには次の2つの方法があります。 def hoge yield end hoge{ p 123 } def hoge(&block) block.call end hoge{ p 123 } ですが、…

Crystal には Thread がなくてつらい

これは「Ruby脳にはCrystalつらい Advent Calendar 2015」の22日目の記事です。 qiita.com タイトルのまんまですが、Crystal は Thread がなくてつらい。 Thread というクラスはありますが、ソースを見ると、 # Don't use this class, it is used internally…

Crystal のバイナリデータ読み込みは C みたいでつらい

これは「Ruby脳にはCrystalつらい Advent Calendar 2015」の21日目の記事です。 qiita.com Crystal の String は UTF-8 固定なのでバイナリデータを String で扱うことはできません。 バイナリデータを扱うには String ではなく Slice を使います。 Slice(UI…

Crystal の型を絞り込む場合は is_a? を使うしかなくてつらい

これは「Ruby脳にはCrystalつらい Advent Calendar 2015」の20日目の記事です。 qiita.com 昨日の記事で、File#gets が nil を返すことがあるので、 line = File.open("/dev/urandom").gets if line.is_a? String # gets は nil を返すことがあるためこの if…

Crystal の文字列は UTF-8 固定でつらい

これは「Ruby脳にはCrystalつらい Advent Calendar 2015」の19日目の記事です。 qiita.com 昨日の記事で Crystal の文字列は UTF-8 だと書きましたが、実行時に外部から UTF-8 以外の文字列を与えるとどうなるのでしょうか。 p File.open("/dev/urandom").ge…

Crystal の文字列は UTF-8 固定でつらくない!

これは「Ruby脳にはCrystalつらい Advent Calendar 2015」の18日目の記事です。 qiita.com Ruby の文字列のエンコーディングはオブジェクト毎に異なる可能性があります。 エンコーディングが異なる文字列を結合したりマッチングさせようとすると例外になりま…

Crystal は文字と文字列が異なっていてつらい

これは「Ruby脳にはCrystalつらい Advent Calendar 2015」の17日目の記事です。 qiita.com Ruby では '〜' と "〜" は両方とも文字列(String)です。文字列を1文字ずつに分割しても、それは1文字の文字列です。 Crystal では '〜' は文字(Char)で、"〜" は文…

Crystal の文字列は変更不可でつらい?

これは「Ruby脳にはCrystalつらい Advent Calendar 2015」の16日目の記事です。 qiita.com 最近 Ruby でリテラル文字列を変更不可にするとかしないとかって話がありますが、Crystal の文字列は最初から変更不可です。 文字列オブジェクトを変更するようなメ…

Crystal は String#to_i がエラーになることがあってつらい

これは「Ruby脳にはCrystalつらい Advent Calendar 2015」の15日目の記事です。 qiita.com Ruby の String#to_i は数字以外の文字列の場合に 0 を返します。C の atoi() と同じです。 % ruby -e 'p "abc".to_i' 0 Crystal の String#to_i は数字以外の文字列…

Crystal は nil.to_i がエラーになってつらい

これは「Ruby脳にはCrystalつらい Advent Calendar 2015」の14日目の記事です。 qiita.com Ruby では nil.to_i は 0 になりますが、Crystal ではコンパイル時エラーになります。 % crystal eval 'nil.to_i' Error in line 1: undefined method 'to_i' for Ni…

Crystal は宣言しただけだと値が未定義になってつらい

これは「Ruby脳にはCrystalつらい Advent Calendar 2015」の13日目の記事です。 qiita.com 昨日の記事に書いたように Crystal は変数を初期化せずに宣言だけすることができます。 ですが、宣言だけだと値は未定義です。未定義のまま参照すると例外が発生した…

Crystal のインスタンス変数が nilable になってつらい

これは「Ruby脳にはCrystalつらい Advent Calendar 2015」の12日目の記事です。 qiita.com Crystal で Ruby と同じような感覚でインスタンス変数を使うと nil だと怒られることがあります。 class Hoge def hoge @hoge = "abc" @hoge.size end end Hoge.new.…

Crystal は Ruby にあるメソッド名がなくてつらい

これは「Ruby脳にはCrystalつらい Advent Calendar 2015」の11日目の記事です。 qiita.com Ruby には同じ機能なのに複数の名前があるメソッドがありますが、Crystal は基本的に1機能に1メソッド名という方針のようです。 それにより Ruby にはあるのに Cryst…

Crystal は配列を展開した引数をメソッドに渡せなくてつらい?

これは「Ruby脳にはCrystalつらい Advent Calendar 2015」の10日目の記事です。 qiita.com Ruby だと、配列を展開してメソッドの引数にすることができます。 arg = [1, "abc", :foo] hoge(*arg) # hoge(1, "abc", :foo) と同じ Crystal だとこれはできません…

Crystal にはタプルがあってつらくない

これは「Ruby脳にはCrystalつらい Advent Calendar 2015」の9日目の記事です。 qiita.com 昨日の記事に「Tuple を使うとらくちんです」というコメントをもらいました。 タプルを使って書きなおしてみます。 [ { 1, "hoge" }, { 2, "fuga" }, { 3, "piyo" }, …

Crystal は配列内要素に対してすべての要素が持つメソッドしか呼び出せなくてつらい

これは「Ruby脳にはCrystalつらい Advent Calendar 2015」の8日目の記事です。 qiita.com Ruby だと、プログラマーが配列の1番目の要素は整数で、2番目の要素が文字列で…といったように決めて、次のようなコードを書いたりすることがあります。 [ [ 1, "hoge…

Crystal があちこちに .crystal というディレクトリを作ってつらい

これは「Ruby脳にはCrystalつらい Advent Calendar 2015」の7日目の記事です。 qiita.com Crystal を何の気無しに使っていると、気がつくと .crystal というディレクトリがあちこちにできています。 Crystal はコンパイル時に .crystal というディレクトリを…

Crystal は配列の範囲外の参照がエラーになってつらい

これは「Ruby脳にはCrystalつらい Advent Calendar 2015」の6日目の記事です。 qiita.com 1日目の記事で配列が自動拡張されなくてつらいと書いたんですが、配列の範囲外の参照もエラーになります。 array = [0, 1, 2] array[3] [4337095] *CallStack::unwind…

Crystal は日本語のドキュメントがあってつらくない!

これは「Ruby脳にはCrystalつらい Advent Calendar 2015」の5日目の記事です。 qiita.com 5日目にして既にネタ切れでもう Ruby は関係ないしつらくもないんですけど、Crystal アドベントカレンダーで日本語ドキュメントがあることを知りました。 www.adventa…

Crystal でも深さが不定の配列が作れてつらくない…?

これは「Ruby脳にはCrystalつらい Advent Calendar 2015」の4日目の記事です。 qiita.com 昨日の記事で、Crystal は深さが不定の配列が作れなくてつらいと書いたんですが、 実際にできないわけないだろうから方法を調べて4日目の記事にしようと思ってたとこ…

Crystal は深さが不定の配列が作れなくてつらい

これは「Ruby脳にはCrystalつらい Advent Calendar 2015」の3日目の記事です。 qiita.com Ruby の配列は任意の型のオブジェクトが入りますが、Crystal は特定の型しか入りません。 空配列を作ろうとするとエラーになります。 array = [] #=> Syntax error in…

Crystal は実行時エラーでソース位置がわからなくてつらい

これは「Ruby脳にはCrystalつらい Advent Calendar 2015」の2日目の記事です。 qiita.com Ruby だと実行時にエラーが発生すると、エラーが発生したプログラムの位置が出力されるのですが、 def hoge raise "hoge" end hoge % ruby hoge.rb hoge.rb:2:in `hog…

Crystal は配列が自動拡張されなくてつらい

これは「Ruby脳にはCrystalつらい Advent Calendar 2015」の1日目の記事です。 qiita.com Ruby だと配列の範囲外に値を代入すると、 array = [0, 1, 2] array[4] = 4 array #=> [0, 1, 2, nil, 4] のように、配列が自動拡張されるのですが、Crystal で同じこ…

Crystal - Ruby風静的型付きコンパイル言語

Ruby で複数人で大きめのプログラムを作ってると、型が欲しいと思うことが時々あるんですが、最近型つきRuby風言語の Crystal というのがあるのを知ってちょっと触ったりしてました。 YAPC::Asia 2015 で、まつもとさんの「絶対に型を書きたくないでござる」…

Ruby + jemalloc でメモリ使用量が増える場合

Ruby でスレッドを1000個ほど作るとプロセスサイズが 4GB ほどになります。 % ruby -e 'system "ps -o vsz -p #$$"; 1000.times{Thread.new{sleep}}; system "ps -o vsz -p #$$"' VSZ 46392 VSZ 4151572 jemalloc 使うと 2.5GB くらいになります。jemalloc …

Ruby, MySQL のうるう秒の扱い

2015/7/1 にうるう秒が挿入されるということで、うるう秒の話題が盛り上がってるようなので自分も書いてみます。 Linux 上のプログラムが時刻で60秒を刻むには、うるう秒対応のタイムゾーンを使う必要があります。 通常はうるう秒を考慮していないタイムゾー…

RSpec をやめて Test::Unit に戻る

最近の RSpec は、それまで obj.stub(hoge: value) と書けたものが、 allow(obj).to receive(:hoge).and_return value と書かないといけなくなったりとか、正気の沙汰とは思えないような変更をしたりするので、何年かぶりに Test::Unit を使ってみようとリハ…

Rubyのシグナルハンドラ

toRuby & guRuby 出張版 でシグナルについてやってたので、関連して書いてみます。 どのような時にシグナルハンドラを定義するのか どのような時にシグナルハンドラを定義するのかという話がありました。 UNIXのデーモンプログラムは、何が由来なのかわかり…

RubyHiroba 2014 に行きました

去年に引き続き RubyHiroba 2014 に行ってきました。 お目当ては toRuby & guRuby 出張版 です。 渋谷の一角の北関東。 咳さん(@m_seki)とか田中さん(@tanaka_akr)とか角さん(@kdmsnr)とか角谷さん(@kakutani)とか豪華メンバーが参加してました。 guRuby - …

Ruby の Timeout.timeout に例外クラスを指定する時の注意

ちょっとハマったのでメモ。 Ruby の Timeout ライブラリを使うと、一定の時間が過ぎても終わらない処理を中断することができます。 require 'timeout' def hoge sleep end def main Timeout.timeout(3) do hoge end rescue Timeout::Error => e p 'main: ti…

Sequel について (その2)

前回 からの続きです。 今回はいろんな SELECT クエリを記述するために使用されるメソッド等について書いてみます。 データセット その前にまずデータセットについて説明します。 テーブルからレコードやカラムを絞り込んだものをデータセットといいます。 D…

Sequel について (その1)

最近 Sequel というライブラリを触ってるので簡単にまとめてみます。 Sequel Sequel は Ruby の構文で SQL クエリを記述するためのライブラリです。 SQL の文法が嫌いな自分には持って来いです。 RDB 毎の差異も吸収してくれます。 自分は MySQL しか知らな…

Rubyでシェルもどきを作る

Ruby でシェルのようなものを作ってみると、Ruby とシェルやシステムコールの理解ができて、研修の課題とかにいいんじゃないかと10年くらい前に思ってたのを、ふと思い出したので書いてみます。 基本 シェルの動作を簡単に説明すると次のような感じです。 プ…

Ruby/MySQLの速度

Ruby 2.1.0 preview1 がリリースされたので、Ruby/MySQL の速度を測ってみました。 測定環境 ThinkPad X220 Core i5 2.3GHz Linux Mint 15 32bit MySQL 5.6.13 測定内容は https://github.com/tmtm/ruby-mysql/tree/master/bench 参照。 ruby-mysql すべて R…

CodeIQ の解答例を Ruby っぽくする

エンジニア夏祭り2013「オラにじぇじぇじぇなコードを書いてくんろ!」解答編 の解答例の Ruby コードがあまり Ruby っぽくなかったので、勝手に Ruby らしくしてみます。 元の解答例 s="gtgtsgipgttptinggipsppaigsesgpetgstpatetisiesagaeaigttetepitiatse…

親子関係のないプロセス間でファイルディスクリプタを共有する

UNIX や Linux でプロセス間でファイルディスクリプタを共有するには、ファイルディスクリプタを作成後に fork して親子間で共有するという方法が良く取られますが、UNIXドメインソケットを使って、親子関係のないプロセス間でファイルディスクリプタを受け…