2013年10月

tmuxで画面をattachしたときに |...................... ってかんじになる場合の対策

他の端末でも attach しているせいで、

            |................................
            |................................
----------................................
.............................................

みたいなかんじで画面がおかしくなる場合は

$ tmux attach -d

として先に attach していたほうを殺して attach すればよい

[Ruby] クラスのネストと継承における参照順位

次のようなコードがあるとする

class A1
  Const = "A1"
end
class A2 < A1
  Const = "A2"
end
class A3 < A2
  Const = "A3"
  class B1
    Const = "B1"
  end
  class B2 < B1
    Const = "B2"
  end
  class B3 < B2
    Const = "B3"
    class C1
      Const = "C1"
    end
    class C2 < C1
      Const = "C2"
    end
    class C3 < C2
      Const = "C3"
      puts Const
    end
  end
end

わかりやすく図に書くと(わかりやすいのかわからないが)こんなかんじ。

A3 < A2 < A1

B3 < B2 < B1

C3 < C2 < C1

さて、puts Const はどのような順番で Const 定数を参照するだろうか。











答えは

C3 -> B3 -> A3 -> C2 -> C1

となる。B2, B1, A2, A1 は参照されません!!!「外」のクラスの「継承」クラスは参照されません!!!昔からこう。

一方次のようにメソッド化した場合はどうか

class A1
  Const = "A1"
  def self.const; Const; end
end
class A2 < A1
  Const = "A2"
  def self.const; Const; end
end
class A3 < A2
  Const = "A3"
  def self.const; Const; end
  class B1
    Const = "B1"
    def self.const; Const; end
  end
  class B2 < B1
    Const = "B2"
    def self.const; Const; end
  end
  class B3 < B2
    Const = "B3"
    def self.const; Const; end
    class C1
      Const = "C1"
      def self.const; Const; end
    end
    class C2 < C1
      Const = "C2"
      def self.const; Const; end
    end
    class C3 < C2
      Const = "C3"
      def self.const; Const; end
      puts const
    end
  end
end

puts const はどのような順番で Const 定数を参照するだろうか。答えは

C3 -> C2 -> C1

となり「外」のクラスは参照されないですね。


おわり 

[Ruby] 標準(エラー)出力を変数に保存する。

$stdout, $stderr を StringIO クラスですげ替えれば変数に保存できる。CLIなツールのテストを書く時とかに役立つ。

標準出力を保存

  def capture_stdout
    out = StringIO.new
    $stdout = out
    yield
    return out.string
  ensure
    $stdout = STDOUT
  end

のようにメソッドを定義しておき、

  output = capture_stdout do
    # 何か $stdout に出力するコード
    puts 'caputre me!'
  end

とすれば output 変数に capture me! を保存できる。

gem の中身がコレだけの capture_stdout という gem があり、それから学んだ。

標準エラー出力を保存

  def capture_stderr
    out = StringIO.new
    $stderr = out
    yield
    return out.string
  ensure
    $stderr = STDERR
  end

のようにメソッドを定義しておき、

  output = capture_stderr do
    # 何か $stderr に出力するコード
    $stderr.puts 'capture me!'
  end 

とすれば output 変数に capture me! を保存できる。$stdout を $stderr に変えただけ

子プロセスの標準エラー出力を保存する

プロセス間通信しないといけないので、パイプを使って子から親へ標準出力/標準エラー出力を渡す

  r, w = IO.pipe
  $stderr = w
  pid = Process.fork do
    # 何か $stderr に出力するコード
    $stderr.puts 'foo!'
  end
  Process.waitpid pid
  w.close
  puts r.read
  $stderr = STDERR

Build ruby trunk

mkdir ruby
cd ruby
git init
git remote add origin -t trunk https://github.com/ruby/ruby.git
git fetch
git co trunk
autoconf
./configure --program-suffix=-head --prefix=$HOME/opt/ruby-head --with-baseruby=/usr/bin/ruby --disable-install-doc # --with-openssl-dir=`brew --prefix openssl`
sudo yum install libyml
make
make install
make test-all -j N # N is number of cpu core
make test-all -j 2 TESTS="webrick openssl"
make test-all TESTS="test/ruby/test_array.rb"
$HOME/opt/ruby-head/bin/ruby-head -v 

ウム!

ssh接続が遅い

mac から会社の環境に ssh で接続しようとすると遅い

$ ssh -v remote_host

のように -v をつけてみると、

debug1: Next authentication method: gssapi-with-mic
debug1:  Miscellaneous failure (see text)
Server (host/xxx.xxx.xxx.xxx@domain.local) unknown while looking up 'host/xxx.xxx.xxx.xxx@domain.local' (cached result, timeout in 246 sec)

こんなのが出ていて、lookup に時間がかかっていたことがわかった。

そもそも鍵で認証していて GSSAPI (Kerberos 認証とか)は使っておらず失敗することがわかりきっているので、クライアント側の設定で使わないようにできないのかぐぐった所、sshの接続が遅い のサイトが引っかかったのでそれにならって、mac の ssh_config をいじった

$ sudo -H vim /private/etc/ssh_config
-    GSSAPIAuthentication yes
+   GSSAPIAuthentication no

速くなった :D
 
 
A Ruby and Fluentd committer working at DeNA. 記事本文および記事中のコード片は引用および特記あるものを除いてすべて修正BSDライセンスとします。 #ruby #fluentd #growthforecast #haikanko #yohoushi #specinfra #serverspec #focuslight
はてぶ人気エントリー