トップ 追記   RSS 1.0 FEED  

Journal InTime


2019-03-08 (Fri) [長年日記]

_ Textbringerグッズ

RubyKaigiに向けてTextbringerグッズを作ってみた。

まず、SuzuriでTシャツやノートなどを作ってみた。ノートは思ったよりサイズが大きかった。

photo

続いて、ラクスルでステッカー。

photo

PVCなのでバイクにも貼れる。

photo

オンラインデザインだとサイズが決め打ち&ラスタ画像しか使えないので、PDFとかで入稿した方が仕上がりがよかったかも。 なお、"SERVE THE BALANCE"は「天秤に仕えよ」という意味で英語を間違えているわけではない。

ロゴ自体はDesignEvoで作成した。解像度が低い画像だけならクレジット表示すれば無料で使えるけど、著作権譲渡を受けたりSVGを入手すると$49.99。フォントも付いてくるのがうれしい。

ぱぱっと作ったわりにそれっぽくできたなと思ってたら、Inkscapeで拡大縮小する時に縦横比が狂ってしまったようで、オリジナルより縦長になってしまった。Inkscapeで拡大縮小する時はCtrl押しながらやらないとこうなるよ! 見慣れたせいかグッズの方がバランスがよい気もする。

ステッカーは100枚作ったのでほしい人がいたらRubyKaigiの時にあげます。 たぶん、黒のパーカーを着てると思うので声をかけてください。


2019-02-24 (Sun) [長年日記]

_ 島根半島ショートツーリング

天気がよかったので島根半島を走ってきた。

photo

のんのんばあって水木しげるのやつだっけ。

この後雲津から境港に抜ける道が思ったより細くて往生した。

photo

写真だとわかりにくいけど、美保関から大山がきれいに見えていた。

Tags: 250DUKE

2018-12-26 (Wed) [長年日記]

_ Ruby 2.6.0

2.6.0が出たのでこのサイト(FreeBSD 11.2)のRubyをアップグレードした。

bundle install時にidn-rubyのビルドで失敗した。

$ gem install idn-ruby -- --with-idn-include=/usr/local/include --with-idn-lib=/usr/local/lib

としたらgem単体のインストールは成功したので、

$ bundle config build.idn-ruby --with-opt-include=/usr/local/include --with-opt-lib=/usr/local/lib

としてみるも、やはり失敗。

$ bundle config  build.idn-ruby --with-idn-dir=/usr/local

としたら上手く行った。

複数オプションがある場合の挙動がおかしい?

Tags: Ruby

2018-12-05 (Wed) [長年日記]

_ 特殊変数のスコープ

(この記事はRuby Advent Calendar 2018の参加記事です。)

Rubyはシンプルな文法が特長である。

Rubyには特殊変数と呼ばれる変数があって、見た目はグローバル変数だが、$_$& などの一部の変数はローカル変数に似たスコープを持っている。「似た」というのは厳密には違いがあって、基本的にブロックローカルではなくメソッドローカルなのだが、スレッドのブロックではスレッド毎に固有の値を持つ。

t = Thread.start {
  Thread.current.name = "sub"
  $_ = "foo"
  5.times do
    puts "#{Thread.current.name}: #$_" #=> 5回とも「sub: foo」と出力
    sleep(0.1)
  end
}
Thread.current.name = "main"
$_ = "bar"
5.times do
  puts "#{Thread.current.name}: #$_" #=> 5回とも「main: bar」と出力
  sleep(0.1)
end
t.join

この挙動は、単純にメソッドローカルにするとスレッドセーフでなくなってしまうからである。 では、以下のように同じProcオブジェクトを別々のスレッドで実行するとどうなるか?

def with_special_var(x, &block)
  Thread.current[:x] = x
  block.binding.eval("$_ = Thread.current[:x]")
  block.call
end

f = -> {
  5.times do
    puts "#{Thread.current.name}: #$_"
    sleep(0.1)
  end
}
t = Thread.start {
  Thread.current.name = "sub"
  with_special_var("foo", &f)
}
Thread.current.name = "main"
with_special_var("bar", &f)
t.join

実は処理系によって挙動が異なる。

CRubyの場合:

$ ruby -v t.rb                          
ruby 2.6.0dev (2018-11-28 trunk 66060) [x86_64-linux]
main: bar
sub: foo
main: bar
sub: foo
main: bar
sub: foo
main: bar
sub: foo
main: bar
sub: foo

JRubyの場合:

$ jruby -v t.rb
jruby 9.2.0.0 (2.5.0) 2018-05-24 81156a8 OpenJDK 64-Bit Server VM 9-Debian+0-9b181-4bpo91 on 9-Debian+0-9b181-4bpo91 +jit [linux-x86_64]
main: foo
sub: foo
main: foo
sub: foo
main: foo
sub: foo
main: foo
sub: foo
main: foo
sub: foo

JRubyでは両方のスレッドでProcオブジェクトを生成した環境の $_ が共有されるが、CRubyの場合はProcオブジェクトを生成した環境とスレッドを生成した環境が同一のメソッド呼び出し(上記の例ではトップレベル)だった場合、 $_ は各スレッド毎に別々の値を持つ。

CRubyでは特殊変数へのアクセスは以下のように実装されている。

static inline struct vm_svar *
lep_svar(const rb_execution_context_t *ec, const VALUE *lep)
{
    VALUE svar;

    if (lep && (ec == NULL || ec->root_lep != lep)) {
        svar = lep[VM_ENV_DATA_INDEX_ME_CREF];
    }
    else {
        svar = ec->root_svar;
    }

    VM_ASSERT(svar == Qfalse || vm_svar_valid_p(svar));

    return (struct vm_svar *)svar;
}

lep はlocal environment pointerでメソッドローカル変数が格納されている領域を指す。 ec->root_lep は各スレッドの実行環境のトップレベルのメソッドローカル変数が格納されている領域を指す。 両者が同じ値の場合、各スレッドのトップレベルの特殊変数を格納する ec->root_svar を返している。

JRubyの実装は読んでいないが、おそらく上記のように特殊変数のアクセス時に動的なチェックを行うのではなく、スレッド生成時にブロックが直接記述されている場合だけを特別扱いしているのだろう。

以下のようにProcオブジェクトとスレッドを別の環境で生成した場合は、CRubyでもJRubyと同じようにスレッド間で $_ の値が共有される。

def with_special_var(x, &block)
  Thread.current[:x] = x
  block.binding.eval("$_ = Thread.current[:x]")
  block.call
end

def make_proc
  -> {
    5.times do
      puts "#{Thread.current.name}: #$_"
      sleep(0.1)
    end
  }
end

f = make_proc
t = Thread.start {
  Thread.current.name = "sub"
  with_special_var("foo", &f)
}
Thread.current.name = "main"
with_special_var("bar", &f)
t.join

Rubyはシンプルな文法が特長である。

Tags: Ruby

2018-11-17 (Sat) [長年日記]

_ スタッドレスタイヤ交換

photo

イエローハットで聞いてみたらタイヤ代だけで10万円以上で工賃別と言われたので、楽天(タイヤホイール激安王国といういかにもな名前の店舗)でスタッドレスタイヤとタイヤ交換チケットを購入してみた。

取付店に直接送ってくれるけど、取付店は選べずに勝手に近くの店を指定されるという仕組みで、希望日時も備考欄に記入しないといけないのでちょっと面倒くさい。自分の場合は、たまたま近くに提携店舗が一つしかなく、希望日時通りに予約できたからよかったけど。

タイヤ自体は無難にヨコハマのIG50 PLUS(205/60R16)にして56,800円(税込)。一つ前のモデルだけど、交換前のIG30でも特に不満はなかったし、商品ページに2018年製造と明記されていて実際届いたものも4本とも2018年35週製造だった。

タイヤ交換(組み換え)チケットは1本1900円(税別)で、廃タイヤの引き取り料を別途店舗に直接1200円ちょっと支払った。 引き取り料はこちらから言わなかったら取られなさそうな感じだったので、まだあまり利用者がいないのかもしれない。