simanのブログ

ゆるふわプログラマー。競技プログラミングやってます。Ruby好き

ruby-growlで日本語を使用する

ruby-growlでタイトルやテキストに日本語を使用しようとするとエラーが発生する。

/Users/siman/.rbenv/versions/2.0.0-p195/lib/ruby/gems/2.0.0/gems/ruby-growl-4.0/lib/ruby-growl/gntp.rb:336:in `join': incompatible character encodings: UTF-8 and ASCII-8BIT (Encoding::CompatibilityError)
	from /Users/siman/.rbenv/versions/2.0.0-p195/lib/ruby/gems/2.0.0/gems/ruby-growl-4.0/lib/ruby-growl/gntp.rb:336:in `packet'
	from /Users/siman/.rbenv/versions/2.0.0-p195/lib/ruby/gems/2.0.0/gems/ruby-growl-4.0/lib/ruby-growl/gntp.rb:376:in `packet_notify'
	from /Users/siman/.rbenv/versions/2.0.0-p195/lib/ruby/gems/2.0.0/gems/ruby-growl-4.0/lib/ruby-growl/gntp.rb:269:in `notify'
	from growl.rb:20:in `<main>'

ソースコードはこんな感じ

require 'ruby-growl'
require 'ruby-growl/ruby_logo'

g = Growl::GNTP.new "localhost", "ruby-growl"
g.add_notification("notification", "ruby-growl Notification",
                   Growl::RUBY_LOGO_PNG)

g.notify "notification", "テスト", "テスト"

エラーの内容的には「UTF-8とASCII-8BITが混ざってるよ」みたいなことなんだけど、ASCII-8BITなんて入れた覚えは無い。と思っていたら

Growl::RUBY_LOGO_PNG

こいつがASCII-8BITだった。ruby_logo.rbのソースを見に行くと

  RUBY_LOGO_PNG = <<-RUBY_LOGO_PNG.unpack('m').first
iVBORw0KGgoAAAANSUhEUgAAA+MAAAPkCAYAAADCge9oAAAACXBIWXMAAMBW
AADAVgGB4Q5XAAKROklEQVR42uz9d7wsR33mjz/Vk0+6V1cRkAQIDFgCgcg5
...
...
...
...
pVKpVJnX/w8gQkh7RJzL/AAAAABJRU5ErkJggg==
  RUBY_LOGO_PNG

base64形式でエンコードされたロゴをunpackメソッドで元に戻していることが判明。この戻り値のエンコードが「ASCII-8BIT」となっていた。


解決方法1

ロゴを使わなければ日本語入力が可能になる。

require 'ruby-growl'
require 'ruby-growl/ruby_logo'

g = Growl::GNTP.new "localhost", "ruby-growl"
g.add_notification("notification", "ruby-growl Notification")
                
g.notify "notification", "テスト", "テスト"

f:id:simanman:20130620232357p:plain


解決方法2

どうしてもロゴが使いたい場合はruby_logo.rbを下のように改変する。

#RUBY_LOGO_PNG = <<-RUBY_LOGO_PNG.unpack('m').first
RUBY_LOGO_PNG = <<-RUBY_LOGO_PNG.unpack('m').first.force_encoding("utf-8")

こんな感じで強制的にutf-8に変換すればよい。

ロゴ有りver

require 'ruby-growl'
require 'ruby-growl/ruby_logo'

g = Growl::GNTP.new "localhost", "ruby-growl"
g.add_notification("notification", "ruby-growl Notification",
                   Growl::RUBY_LOGO_PNG)

g.notify "notification", "テスト", "テスト"

f:id:simanman:20130620232702p:plain

これでタイトルやテキストに日本語が使用可能になります。