LoginSignup
8
2

More than 5 years have passed since last update.

Rubyを絵文字で書けるようにするGemつくった

Last updated at Posted at 2018-08-30

まえがき

プログラマ歴半年弱で文系の僕には横文字は刺激が強すぎて辛かったので、
もっとポップになればプログラミングも楽しくなるはずだと思い、
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

スクリーンショット 2018-08-31 3.18.13.png
例えばこの謎絵文字と謎絵文字は連続のようでいて、ユニコード的には1F3F6が飛んでいます。

こういった飛び地があるので、適当な範囲の絵文字を適当にアルファベット/記号に変換すると、
その文字が飛び地にあたった場合、「aとcは絵文字で表現できるけどbに対応する絵文字が無い」みたいな辛さが発生します。

したがってアルファベットや記号をどれだけシフトさせるか(どのように対応させるか)が大事になってきます。

眠くなってきました。続きは需要がありそうだったら書きます。

テストも書いてないしバグも多い気がするのでマサカリお待ちしてます。

8
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
2