まえがき
プログラマ歴半年弱で文系の僕には横文字は刺激が強すぎて辛かったので、
もっとポップになればプログラミングも楽しくなるはずだと思い、
Rubyを絵文字で書けるようにするGemを作りました。
つくったもの
Github
RubyGems
RubyGemsにもプッシュしてるので
https://rubygems.org/gems/emozi
グローバルにインストールするなら(非推奨)
$ gem install emozi
or
適当なディレクトリで
# Gemfile
gem 'emozi', '~> 0.0.4'
$ bundle install
で使えるようになります。
使い方
require 'emozi'
💆💋💊💉
🐶🐻🐻👞
👻💂💂💅
🐶👭💅💈
💂👺🐷🐻
# => Hello World!
といった感じで絵文字でRubyが書けます。
def hoge(x, y)
p x + y
end
hoge(1, 2) # => 3
↑このコードだと、こういうふうに書けます↓
require 'emozi'
👺👻👼🐶👾💅👽👻🐾💎
👂🐶💏🐿🐠🐶💆🐶💎🐶
👁🐶💏🐠👻💄👺🐠🐠👾
💅👽👻🐾👇👂🐶👈🐿🐠 # => 3
絵文字に明るくない方のためにコードを絵文字に変換するメソッド #emozify
も用意しました。
require 'emozi'
emozify('p "hoge"') # => 💆🐶🐸👾💅👽👻🐸
複数行のコードにも対応してます。多分。
時々変換できないコードもあります。黒魔術系のコードは変換出来ない傾向にあります。
どうやってつくったか
実装自体は14行しかないので、実装の中身の話はコードを読んでもらったほうが早いかなと思います。
https://github.com/rnitta/emozi/blob/master/lib/emozi.rb
MAGIC_NUMBER = 128_022
$🤔 = ''
def emozify(str)
puts str.chars.map { |char| (char.ord + MAGIC_NUMBER).chr('UTF-8') }.join
end
def method_missing(emoji, *_)
$🤔 << emoji.to_s
end
at_exit do
eval$🤔.chars.map { |char| (char.ord - MAGIC_NUMBER).chr('UTF-8') }.join
end
method_missing
で絵文字をメソッド名として第一引数でシンボル化された絵文字が取れるので、
グローバル変数のstringにto_sしてくっつけていき、
at_exit
で終了時に変数に格納された絵文字をコードに変換してevalで実行してるだけです。
emozify
はなくても動くので、実装は実質8行ぐらいです。
以下作り方というか何を考えてつくったかいうポエム↓
前提
もしかしたらご存じない方もいるんじゃないかと思いますが、
Rubyは変数名やメソッド名に日本語が使えます。
(そんなにめずらしいことではない)
なので、
def 引数を2倍にして返す関数(引数)
引数 * 2
end
伍 = 5
引数を2倍にして返す関数(伍) # => 10
こんなことができます。擬似コードじゃないですよ。
日本語が使える、というよりマルチバイト文字が使えるので、当然絵文字も使えるわけです。
そうすると次は絵文字だけでコードが書きたくなりますね。
eval
みんな大好きevalを使えばなんでもできます。
evalは引数の文字列をコードとして解釈して実行してくれるので、
(入力)絵文字 → コードに変換 → evalで実行(出力)
というフローに思い至ります。
絵文字をどうやってコードに変換するか
絵文字にも、アルファベットや記号にも当然Unicodeが振られてますから、
絵文字のユニコードをアルファベットや記号のユニコードまでシフトさせちゃえばいいわけです。
しかしここで問題が発生します。
絵文字のユニコードは必ずしも連番とは限らないのです。
参考: https://ja.wikipedia.org/wiki/Unicode%E3%81%AEEmoji%E3%81%AE%E4%B8%80%E8%A6%A7
こういった飛び地があるので、適当な範囲の絵文字を適当にアルファベット/記号に変換すると、
その文字が飛び地にあたった場合、「aとcは絵文字で表現できるけどbに対応する絵文字が無い」みたいな辛さが発生します。
したがってアルファベットや記号をどれだけシフトさせるか(どのように対応させるか)が大事になってきます。
眠くなってきました。続きは需要がありそうだったら書きます。
テストも書いてないしバグも多い気がするのでマサカリお待ちしてます。