へっぽこびんぼう野郎のnewbie日記

けろけーろ(´・ω・`)! #vZkt8fc6J

指定したディレクトリ下にある全ファイルの拡張子を見るコマンド

コマンド

$ find <Directories you will search> -type f | sed 's/.*\.\(.*\)$/\1/g' | sort | uniq

$ find */templates -type f | sed 's/.*\.\(.*\)$/\1/g' | sort | uniq
css
html
js
txt

もちろんファイルの個数を数えることもできるぞい!

 find */templates -type f | sed 's/.*\.\(.*\)$/\1/g' | sort | uniq -c
   1 css
 239 html
   8 js
   6 txt

パワポのファイルがぶっ壊れてるときの修復のしかた

Open XML SDK 2.5 Productivity Tool を使う

stackoverflow.com

↑ここに詳しく書いた

ㇹ゚ン゚'ㇳ̃ヴ゙ニ゙コ゚ヮヰ文̂字̠コ゚−ト゚ノ゙ㇵナ゚ㇱ(現在に至るまでの文字コードの軌跡と簡単な使い方について)

はじめに

社内の勉強会で発表した文字コードの話の焼き直しです。ところどころ適当なので話半分に読んでもらえると助かります。

これ以上闇の深さを知りたくないと思って、深淵に辿り着く前に文字コードの勉強を打ち切っています。文字コードの専門家でもないので雑です。 調査が甘いので間違ってることも多々あるかもしれません。その場合はコメントください。修正します。

自信のないところは「らしい」とか「ようです」などのように伝聞調で書いています。あらかじめご了承ください。

また、前提知識として2進数と16進数の基礎的な知識を要求しています。

16進数の表現には特に断りがないかぎり 0xFFFF のような表現を使います。

2進数を使う場合には必ず断り書きを入れます。それ以外は10進数です。

本筋には関係のない、重要ではない情報は脚注にあります。気になったところだけご覧ください。

アジェンダ

  1. 今回の話に関係ある用語
  2. 現代の文字コード事情(Unicodeとその他)
  3. ASCIIから現代まで
  4. UnicodeUTF-16
  5. UnicodeUTF-8
  6. まとめ

1. 今回の話に関係ある用語

文字コードの規格に関する用語として次のものがあるので、軽く説明します。

ISO

International Organization for Standardization (国際標準化機構)

道路標識とかマネジメント規格とか長さの単位とか、国際標準のものならなんでもとりあえず決めている組織

規格が決まっていないと、連携するときにいちいちサイズなりやり方なりを合わせたりしないといけないので、国際的に決めて便利にしておこう的組織。

IEC

International Electrotechnical Commission (国際電気標準会議)

電気関係の標準を決める組織。水車とか同軸ケーブルとかの規格を決めてる。

文字コードの国際規格では、ISOとIECでどちらが標準を決めるのか縄張り争い的な感じになったらしく、結果的にISOとIECが両方絡むことになった(イイネ!!)

JIS

Japanese Industrial Standards (日本工業規格)

JSA(日本規格協会)が決めている日本の標準規格

トイレットペーパーのサイズとか畳のサイズとか決めてる

文字コードの件でも色々絡む

2. 現代の文字コード事情(Unicodeとその他)

ひとまず、現代の文字コード事情がどうなっているのかという、ぼくが勉強する前にはじめに思った疑問と闇をざっくりと祓っていきます。

そもそも文字コードとは?

一般的に使われている「文字コード」という言葉は、

文字やバイト列を入れると、それに対応したバイト列や文字が返ってくるやつ!

という概念を示したものだと思います。*1

なぜなら、さまざまなアプリケーションで「好きな文字コードを選んでね♡」というふうに書いてあって、

その選択肢として「Unicode(UTF-16)UTF-8Shift JIS」などが提示されるからです。

そのため「Unicode文字コード」「UTF-8文字コード」「UnicodeUTF-16は同じ」というような理解が世間的に了解されていると思います。

この概念はすごく便利なので、あまり詳しくなくても「文字を入れるとなんかバイト列になる」という知識で、文字をコンピュータで扱えるので重宝されています。

しかし「文字コード」と一言で言っても、一概に全部が全部同じような「文字コード」というわけではありません。

それぞれの文字コードには、歴史的な経緯があり、人間的な努力があり、ドラマがあり、互換性のためのテクニックが存在しているため、外面は同じように見えて、中身の実装が違うからです。

よく聞く文字コードたち

現代でもよく使う、かなり知られている文字コードですが、やっぱり「UnicodeUTF-16の関係は?」とか「結局Unicodeってなんだよ?」「Shift JISのShiftってなんだよ?」と聞かれると、ぼくはパニックになっていました。

まずはとりあえず、Unicodeとその他の文字コードの関係を説明します。

Unicodeとは?

Unicodeとは、Unicodeコンソーシアムで作られている文字コードです。コンソーシアムというのは共同事業体という意味です。日本の企業も参加しています。

Unicode Consortium

Unicodeという言葉は、色んな文脈によって使われ方があるのですが、文字コードとしてのUnicodeではなくて、そもそものUnicodeを説明したいと思います。

その場合、Unicodeとはざっくり言うと、文字と、文字に対する番号(16進数)の表です。

たとえば、下のように「あ」に対して「3042(16進数)」番が振られています。

f:id:haruharu1:20180428144400p:plain

ここですべてを見ることができます→https://unicode-table.com/en/#hiragana

Unicodeのこの表には、ラテン文字(英語で使うアルファベット)やキリル文字、ひらがなカタカナはもちろん、ハングルもあり、ヒエログリフ線文字B、そして絵文字など、かなりの文字が含まれています。ただ当然、全世界のすべての文字が含まれているわけではないことにご注意ください。

Unicodeでの文字に対する位置を表すときは、16進数の前に U+ をつけて表すことが多いです。

U+3042U+1F439🐹を表します。

このUnicodeでの文字に対する位置【例: U+3042】 を、CodePoint(コードの位置という意味)と呼びます。

たとえば、のCodePointはU+3042です。

Unicodeの実際の使われ方の例

プログラミング言語Pythonの、3.x系では、文字列型str(文字型charはありません)を、Unicodeで表現しているので、次のようなことができます。

$ python
Python 3.6.5 (default, Mar 30 2018, 06:41:53)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> chr(0x3042)
'あ'
>>> chr(0x1F439)
'🐹'
>>> '\U00003042'
'あ'
>>> '\U0001F439'
'🐹'

その他の文字コード

その他の文字コードは、Unicodeの子分のような存在です。他の文字コードの値は、UnicodeのCodePointに変換されます。その逆もします。

たとえばUTF-8の値、E3 81 82(16進数)が与えられたときに、U+3042を吐き出します。

逆も同じで、UnicodeのCodePointU+3042が与えられたとき、これをE3 81 82(16進数)に変換します。

そんなかんじで、 E3 81 82 を変換したら U+3042 になったから、Unicodeの表でいうと だなと変換されて、ディスプレイに表示されます。

そのほかの文字コードもそうです。(以下の数字は16進数です)

CP932 は、Microsoft実装のShift JISのことです。 *2

[UTF-8]
E3 81 82 -> U+3042

U+3042 -> E3 81 82

U+1F439 -> F0 9F 90 B9
[UTF-16]
30 42 -> U+3042

U+3042 -> 30 42

U+1F439 -> D8 3D DC 39
[CP932]
82 A0 -> U+3042

U+3042 -> 82 A0

U+1F439 -> 無理

例として、python3.xでUTF-8エンコードすると、このようになります。*3

この は、Unicode で、つまりpython内部では U+3042として取り扱われています。

>>> 'あ'.encode('utf-8')
b'\xe3\x81\x82'
>>> '🐹'.encode('utf-8')
b'\xf0\x9f\x90\xb9'

クイズ

もう1つ例として、HTMLを使ってみます。

以下は、UTF-8 で書かれた htmlファイル です。 shift_jis で表示しろと書いてありますが、この場合、ブラウザではどのように表示されるでしょうか?

f:id:haruharu1:20180428152605p:plain

こたえ

f:id:haruharu1:20180428152707p:plain

まずテキストファイルは、UTF-8エンコードされたものになっています。

それをブラウザがShift JISだと解釈してデコードします。

最後に、&#x〜〜〜(Numeric Character Reference【NCR】)などをデータとして受け取ったブラウザは、これをUnicode表と対応させて、文字を表示します。

python3.xで実際にやってみると↓のようになります。

>>> '&#x1f439;'.encode('utf-8').decode('cp932')
'&#x1f439;'
>>> '🐹'.encode('utf-8').decode('cp932')
'\ue05e聖'

クロスサイトスクリプティングを防ぐために、<script></script>&gt;を使ったものに変える必要があるのは、このためです。 *4

Unicodeとその他の文字コードとの関係

だいじなのは、Unicodeとその他の文字コードの関係で、とりあえず「なんでもかんでもUnicodeのCodePointにするのか」という感じで了解してもらいたいです。

でも、もともと文字コードが誕生したときから世界がこういう思想で動いていたわけではなくて、さまざまな人達がその時代時代で最善の選択肢を取ってきたことによって、今の現状があるわけなので、その経緯をざくっと説明したいと思います。

3. ASCIIから現代まで

有名な文字コード関係の規格たち

これらをすべて同じ「文字コード」とするのは無理があるのですが、ひとまずこれらについて説明していきます。

かなり大まかなものなので、「厳密に言うと全然違う」みたいな話もありますが、ご了承ください。

日本で有名なものだけ抜粋したので、もちろん他にもいっぱいあります。

ASCII

  • American Standard Code for Information Interchange(情報交換のためのアメリカ標準符号という意味)
  • 1960年〜
  • 7bitでアルファベットと少しの記号を送るための規格

超絶有名な規格で、 2進数で100 0001(0x41)と送ると、「 A をコンピュータ上で表示する」というような極めてシンプルな規格です。

f:id:haruharu1:20180428160550p:plain

ISO/IEC 646

  • ASCIIっぽいものを、アメリカ以外でも当然自分たちの言語として使いたいという欲求が当然出てくるので、各国語版として存在させるために作られた規格
  • ASCIIの一部の文字を、各国自由に使っていいよと定めた
  • ASCIIと、各国語版を切り替えて使うことができるように、7bitのときは制御文字を用い、8bitのときは最上位ビットが0だったらASCII、最上位ビットが1だったら各国語版を使うのような使い方をしていた
  • 1962年〜

↓ここの緑色になっている部分を自由に各国で決めることができました。

f:id:haruharu1:20180428161021p:plain

JIS X 0201

  • ISO/IEC 646の日本語版。7bitか8bitで使う
  • 1969年〜
  • コウイウカンジデニホンゴヲヒョウジシテイタ
  • ASCIIと違うのは、\~ (今もなおWindowsで残る問題)

ひらがなではなく、カタカナを用いたのは当時のグラフィック能力によるものだと思われます(ひらがなだと文字がドットで潰れる)

f:id:haruharu1:20180428161337p:plain

JIS X 0201 らへんの日本の風潮

  • コンピュータでまともに表示できない言語など欠陥品 (ナンデカタカナデシカツカエナイノ!? アメリカでは何の問題もない)
  • 新聞もコンピュータで印刷できない(活字拾い大活躍。まだまだ全然活版印刷の時代)
  • 日本語は漢字を廃止してローマ字化すべき (アルファベットなら文字が少なくて済む)
  • 国が出している漢字表も、「常用漢字表」ではなく「当用漢字表」(さしあたってとりあえず使う漢字)だった
  • 戦後なので、とりあえず日本語disしておけばいい状態

こういう時代だったので、ひらがなと漢字が表示できるコンピュータを作るか、日本語やめるかという状況だったみたいです。

↓40年前のこの時代に使われていた和文タイプライターがこんな感じで、下に見える1つ1つのハンコっぽいやつが漢字です。

f:id:haruharu1:20180428162336p:plain

アメリカではタイプライターで文字探しなんかしなくていいし、コンピュータをガンガン使えるのに、日本では文字探しをしなければいけないしコンピュータ使えないという時代だったようです。

これで仕事しなければいけないとか言われたら、そりゃ文豪も怒りが有頂天になって日本語廃止したくなりますわっていう納得感を感じます。

JIS X 0208

  • 1文字に2バイト使ってもコンピュータが問題なく動く、メモリが潤沢な時代が到来
  • 94×94の8836文字使える(94という数字はASCIIから制御文字を取り除いたときの数)
  • ある程度まともに日本語が使えるようになって日本語廃止論者がいなくなる
  • ここで追加されたのが第1水準、第2水準漢字
  • この時代では、互換性のために必要に応じてJIS X 0201JIS X 0208を切り替えて使っていた(重要!!)
  • なので、JIS X 0208単体でも使えるように、JIS X 0208にもカタカナや英数字があった。
  • 1978年〜
  • 78年にできたので、78JISと言われる。

常用漢字表制定

1981年、常用漢字表制定。

日本語廃止論が収束して、漢字使うぜっていう流れになったので「いつも使う漢字たち♡」という意味の、常用漢字表が作成されました。

そして……

JIS X 0208 (1983年改訂)

常用漢字表の改訂に合わせて、既存の文字を変えることになりました。

たとえば飛驒の「驒」が「騨」になり、
これによって83JISを実装したコンピュータでは「飛騨」と表示されるようになりました。

そのため、正式名は「飛驒」なのにもかかわらず、この改訂によって全国的に「飛騨」という漢字で知られるようになります……

f:id:haruharu1:20180428163143p:plain

今後は、この失敗を省みて、既存の文字を変更するということは日本では行われていないようです。

Shift JIS

  • 1982年〜
  • アスキー社やMicrosoftなどが共同でつくった
  • それまでシステムに応じてJIS X 0201JIS X 0208を切り替えて使っていたので、切り替えをせずに、JIS X 0201JIS X 0208を同時に使えるようにしたかった(めっちゃ便利だしMicrosoftが実装したので市場を席巻した)
  • JIS X 0201の未定義部分を拡張していっぱい文字入れれるようにした(文字通り、JISをシフトした)
  • JIS X 0201の英数字やカタカナを「半角英数字・半角カナ」と呼び、JIS X 0208の英数字やカタカナを「全角英数字・全角カナ」と呼ぶことにした

JIS X 0212

  • 1990年〜
  • JIS X 0208だけじゃ漢字足りないし、人名・地名を中心にいっぱい追加した
  • Shift JISはこの規格に準拠してない(だってShiftしたし)
  • ISO-2022-JPとかeuc-jpとかがこの規格

ISO/IEC-8859-1 (a.k.a ISO-8859-1, Latin-1)

  • 1992年〜
  • 8bitでかなりの数が表現できる画期的な文字コード
  • 各国で自由に使っていたものをすべて右側(最上位ビットが1の場合)に統合した
  • 現在も欧米では使われる
  • 世界中の色んな国ではこれでほぼ問題ない

f:id:haruharu1:20180428164325p:plain

UnicodeISO/IEC 10646

  • 世界の文字をすべて取り入れた文字コードを作れば、もう世界は混乱しないという方針のもと作られた
  • 16bit(65536文字)で世界中の文字を表現するようにした

もともとは、ISO/IEC 10646という規格と、Unicodeという規格は別々のものでした。

ISO/IEC 10646は、ISOとIECで作られていたものでしたが、Unicodeは前述のUnicodeコンソーシアムで作られていました。

しかし同じような規格が乱立するのは好ましくないとされて、合流することになりました。

なので、ISO/IEC 10646側の用語と、Unicode側の用語があります。

最初の方のUnicode

  • 1991年〜
  • 欧米勢「16bitで、世界の文字を表現しよう」
  • 日本・中国・韓国「16bitだと最大65536通りだぞ。無理に決まってんだろ!2バイトやめろ!俺たちだけで超えるわ!殺す!」
  • 欧米勢「2バイトで十分!漢字は場所取りすぎ!まず同じ漢字はまとめてからクレームは言ってね!!!」→CJK統合漢字(Chinese-Japanese-Korea)
  • アラビア語圏「落ち着けお前ら、俺達はまず文字は、右から左に書きたい!」
  • ベンガル語圏「文字と文字がバラバラだけど、どうやって文字くっつけるんだ。こんなの俺たちの文字じゃねぇ」
  • 韓国「なんでハングルを他の言語の文字と文字の隙間に入れるんだ!移動しろ!」→ハングル大移動
  • モンゴル「うちは基本、文字は縦書きなんだけど!」
  • 誰か「文字は文字だけ入れろ!構造を示す文字ってそんなのいらねえだろ!」
  • 誰か「ルビ文字とか入れたい!絶対役に立つ!(役に立たなかった)」

カオス。当初の崇高な目的は理想論すぎました。

最初ぼくは「16bitで世界の文字を表現とか、明らかに無理だろわろすw」と思っていましたが、国際標準の場に立つとそんな「当たり前のこと」が当たり前ではなくなってしまうことがよくあるらしいということを知りました。

自分の要求を押し通すには、他の国の要求も飲まなければいけないわけです。

たとえば日本勢は「右から左に書くとか仕様が複雑になるだけでしょ」って感覚だったとしても、アラビア勢にとっては死活問題で、それと同じように、日本勢が「漢字いっぱい入れろ」っていうのを押し通すためには、他の国々の言い分を聞き入れて、味方につける必要がありました。めちゃくちゃ大変そう……

JIS X 0213

Unicodeが落ち着きはじめた20世紀後半、日本ではまだまだ戦いが続いていました。まだまだ使えない漢字があったので、新しい規格がつくられました。

それがJIS X 2013です。ただ、だんだんUnicodeが隆盛していきます。

  • 2000年〜
  • JIS X 0208の上位互換。JIS X 0212との互換性は無し
  • あとあとUnicodeに文字が取り入れられた
  • Shift JISでは使えない
  • 第三水準・第四水準漢字はここで追加された

どうでもいいことですが、このあたりで、携帯ベンダが絵文字を発明し、文明がより豊かになり、あたらしい地獄が始まりました。

歴史まとめ

だいたいこんな流れだと思っています。

ASCII → JIS X 0201

JIS X 0208(78JIS) -> JIS X 0208(83JIS)

JIS X 0201 + JIS X 0208 -> Shift JIS -> 色んなベンダによるShift JIS実装

JIS X 0212 -> euc-jp, ISO-2022-JP-1

JIS X 0213

16bitですべてを表現するUnicode -> 世界各国の文字コードを吸収する方針へ(現代のUnicode)

4. UnicodeUTF-16

UTF-16とは

最初、Unicodeは16bitですべての文字を表現しようとしていました。

でもやっぱり、16bitは、U+0000U+FFFF までの65536文字しか表現できない……

そこで U+10000 よりも後の文字を表現するために16bitを2つくっつけて、0xD800 0xDC00のようにし、この場合は U+10000 である!ということにしました。

こういった方式を UTF-16 といいます。

また、0xD800 0xDC00 のような組み合わせを、サロゲートペアと呼びます。

サロゲートは「代理」という意味で、つまりUnicodeの実際のCodePointを表すための代理の値の組がサロゲートペアだということです。

は、U+3042なので、0x3042と表すけど、 🐹は、U+1F439だから、これを表すために、0xD83D 0xDC39 のような表現をするということです。

このサロゲートペアという仕組みによって、UnicodeU+10FFFF までの文字が表現可能になりました。(苦肉の策的な感じですが……)

だから、 Unicode(UTF-16) みたいな書き方をたまに見かけることがあります。この場合は、 単にUTF-16 という意味だと思えばいいと思います。

サロゲートペアとUnicodeの実際のCodePointについての計算式は、以下を参照してください。

JavaScript’s internal character encoding: UCS-2 or UTF-16? · Mathias Bynens

RFC 2781 - UTF-16, an encoding of ISO 10646

ちなみに、本当に16bitだけのUnicodeのことを UCS-2 とかって言っていたみたいです。 *5

JavaScriptでの例

JavaScriptでは、UTF-16をStringとして使っているので、次のような感じになっています。🐹の文字の長さが2になってしまうのもUTF-16だからです。

f:id:haruharu1:20180428171502p:plain

なので、どうしてもUnicodeの文字として文字数をカウントしたい場合は、サロゲートペアなどを考慮して実装する必要があります。

これらサロゲートペアを用いた、U+10000 以上の文字は、俗に 4バイト文字 などと呼ばれますが、あまり本質を表していないので、こう呼称するのはやめたほうがいいと思います。

たとえば、 ト゚ は、サロゲートペアを用いてないですが、UTF-16では4バイトで、UTF-8では6バイトになります。 ト゚゚ は、UTF-16では6バイトですが、UTF-8では9バイトです。

5. UnicodeUTF-8

UTF-8は、ASCII互換の文字コードで、これもUnicodeのCodePointに対応するように作られました。

ASCII互換になっている例として、UTF-16では、たとえば A0x0041 と表現されますが、UTF-8では0x41です。

↓こんな感じです。python3では、バイナリは基本的にasciiで表現され、asciiじゃなければ \xNN で表現されます。 utf-16bebe は、ビッグエンディアンです。これらの説明は面倒なので省略します。

>>> 'a'.encode('utf-16be')
b'\x00a'
>>> 'a'.encode('utf-8')
b'a'

UTF-8では、ASCIIじゃないものはすべてUnicodeの表に帰着するように計算されます。

↓のような感じでUnicodeの数字を表現しようとしています。

f:id:haruharu1:20180428173204p:plain

このへんで僕は文字コードから興味を逸しているので、UTF-8の詳細な実装については他のサイトを御覧いただきたいです。

6. まとめ

  • 現在のUnicodeは最強
  • Shift JISは、使えない文字がたくさんあるので、もう使うべきではない。CSV出力?UTF-16でやってね!!
  • UTF-16UTF-8は怖くない
  • 文字コードの闇は、コンピュータの発展と言語そのものの複雑さと、政治的なゲームに起因するもの
  • 昔の人ががんばってくれたおかげで、文字コードがこれぐらいの混乱で済んでいることに感謝する
  • とりあえずこのあたりがわかると文字コードの勉強が開始できる

リファレンス

ASCII + ISO/IEC 646 + JIS X 0201

ASCII - Wikipedia

2002年12月号 特集 第1章

2002年12月号 特集 第1章

JIS X 0208

小形克宏の「文字の海、ビットの舟」

「飛騨」と「飛驒」? どちらも正解ですが公文書は旧字体(旧漢字)です – 村坂克之 小又接骨院のブログ 飛騨・高山・下呂

Shift JIS

ftp://unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP932.TXT

Encodings of Japanese

Code page 932 (Microsoft Windows) - Wikipedia

ISO/IEC 8859-1

ISO 8859-1 Charset

ISO/IEC 8859-1 - Wikipedia

タイプライター・活版印刷

和文タイプライター 日本語タイプライター

活版印刷職人・加藤隆男さんの「活字拾い、組版、印刷から裁断」まで - YouTube

UTF-16

UCS-2とUTF-8

JavaScript’s internal character encoding: UCS-2 or UTF-16? · Mathias Bynens

http://unicode.org/versions/Unicode3.0.0/ch03.pdf

Let’s talk about Javascript string encoding | Kevin Burke

UTF-8

UTF-8からSJISに文字化けすると糸偏の漢字がよく出てくる - Qiita

文字化けパターンサンプル - instant tools

文字コード考え方から理解するUnicodeとUTF-8の違い | ギークを目指して

パソコンは日本語をどう変えたか―日本語処理の技術史 (ブルーバックス)

ユニコード戦記 ─文字符号の国際標準化バトル

いま日本語が危ない―文字コードの誤った国際化

プログラマのための文字コード技術入門 (WEB+DB PRESS plus) (WEB+DB PRESS plusシリーズ)

その他いろいろ

*1:もちろん厳密な定義ではありません

*2:Shift JIS内でも闇があるのですが、現代っ子のぼくは「自分に関係ないし辛そう」と切り捨てて全く調べてません。

*3:UTF-16で試す場合はBOMなどに、また、出力されるバイナリはasciiで表現されることに注意してください。'a'.encode('utf-8')が'a'になるのはこのためです。python2.x系ではバイナリがstr型だったため、こういう風になっているのだと思います(勘)

*4:ちなみにCSSでもできるので、xCSSで修飾することもできます。

*5: UCS-4とかUTF-32とかもあります。

Docker+MySQLで物理バックアップを取得 & リストアする

InnoDBなので、その他はしらん

docker-compose.yml とかに↓のようなものが書いてあると思う

version: "2"
services:
  db:
    image: "mysql:5.7.12"
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: ""
      MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
      MYSQL_DATABASE: ${DB_NAME}
      MYSQL_PASSWORD: ${DB_PASSWORD}
      MYSQL_USER: ${DB_USER}
    command: mysqld --character-set-server=utf8 --collation-server=utf8_general_ci
    restart: always
    volumes:
      - "./volume:/var/lib/mysql"

そうすると、volumeディレクトリがdocker-compose.yml下に作成されている

$ cd ./volume
$ ls
auto.cnf           ib_buffer_pool     ib_logfile1        ibtmp1             performance_schema
ib_logfile0        ibdata1            mysql              sys

↑こんなん

これが、コンテナ内のデータディレクトリと同期している。(適当なファイルを作ると確認できる)

データディレクトリは、mysqlで↓を打つとわかる

> SHOW GLOBAL VARIABLES LIKE 'datadir';

それでこれをどこかにコピーする(物理バックアップ完了)

$ cp -r ./volume ~/backup-directory-where-you-want-to-lay

その後データベースを触って煮るなり焼くなりしたあと、↓をやるとデータベースが復元する

$ cp -r ~/backup-directory-where-you-want-to-lay ~/docker-directory-which-you-created

それでmysqlを再起動

$ docker exec -it <your-docker-container-name> service mysql restart

これでうまくいく。

docker-compose.yml があるディレクトリに↓のスクリプトを置くのもアリ。

#!/bin/sh
cp -r ~/backup-directory-where-you-want-to-lay ~/docker-directory-which-you-created
docker exec -it <your-docker-container-name> service mysql restart

ステージングのデータとかでちょっとしたテストを何度もやるときに便利

おまけ

コンテナ内に入るときはこう

$ docker exec -it <your-docker-container-name> /bin/bash

Reference

innodb - How to take physical backup of MYSQL database - Database Administrators Stack Exchange

MySQL :: MySQL 5.7 Reference Manual :: 14.18.1 InnoDB Backup

JavaScriptで16進数の四則演算の計算ドリルつくった

こんなかんじのやつ

f:id:haruharu1:20180401214028p:plain

Enterを押すと正誤判定してくれます。(=スマホだと動かない)

切り替えて使える

f:id:haruharu1:20180401214143p:plain

f:id:haruharu1:20180401214250p:plain

作った動機

文字コードの勉強してて、16進数の足し算引き算で苦しんでいたため。計算ドリルあったらいいのになと思ったのでつくった。

使い方

$ git clone https://github.com/harukaeru/CalculationDrillBase16.git
$ npm install
$ npm start

これでローカルサーバが立ち上がるのでそこで楽しんでください。

他のサーバと通信などは特にしてないです。全部JavaScriptです。

試してないけど、古いnodeだとインストールできないかもしれないです。

俺専用の問題をつくりたいんだけど??って人へ

window.changeProblemsという関数を用意したのでそれにオプションを入れて実行してください。JavaScriptのライブラリであるlodashも使えます。

↓こんな感じです

window.changeProblems({
  leftRange: () => _.range(0x1, 0x3),
  rightRange: (left, calcType) => _.range(0x1, 0x3),
  calcTypes: ['+']
})

f:id:haruharu1:20180401214828p:plain

ざっくり解説

左側の値(left)はleftRangeで指定した範囲の中からランダムに選ばれたものになります(↑の場合なら0x01か0x02のどちらか)。

calcTypecalcTypesからランダムに選ばれたものが入ります(↑の場合は1個しかないので絶対'+')

それで、この計算されたleftcalcTypeをもとにrightRangeの範囲を決めることができます。(別に使わなくてもいいです。↑の例は使ってません)

rightRange: (left, calcType) => _.range(0x01, left + 1)のようにすると、絶対左側の値を越えないように右側の値を決めることができます。

↓デフォルトで組み込んだやつはここなので、適当に参考にしてください。 https://github.com/harukaeru/CalculationDrillBase16/blob/master/js/configs.js

ちなみにデカい数字入れると落ちますが仕様です。

ソース

github.com

その他

  • バグがあったらごめんなさい。テストなのにテストがないです。ESLintもないです。issueくれれば直します。
  • Redux入れるのめんどくせえなと思って、ないまま作ってたら見事なアンチパターンになってしまったのでコードは参考にしないでください
  • CSSは知らないので雑です。class名とかつけたので適当にデザイン変更してくれると嬉しいです。PRほしいです
  • ちょっと改造すると10進数や8進数や2進数のものとしても使えると思います。ご家庭でご活用ください

JavaScript界隈の基本的な用語を歴史とともにさらにまとめてみた

https://qiita.com/sinsengumi/items/e20342d13cbdd7ac2304 を読んで、すこしだけもやもや感がぬぐえなかったので、適当に自分が思ってる「今のJavaScriptはこんなかんじ」というのを書いた。

EcmaScript

だいじなこと

EcmaScriptとは、プログラミング言語ではない。

EcmaScriptとは、Ecmaインターナショナルが決めているJavaScript言語仕様のこと。

Ecmaとは、European Computer Manufacturers Association の略で、要は世界のコンピュータ関連の仕様を決めてる闇の組織みたいなところ。 (→History of Ecma

なんでEcmaScriptとかいうものがあるのか?

大昔、JavaScriptという言語はHTMLやCSSの「おまけ」扱いだった。

当時のブラウザベンダ(NetScapeIE)が自分たちの好きなようにJavaScriptを作っていたので、Webサイト開発者がサイトを開発するとき、彼らは各ブラウザの独自仕様を理解して同じような動きをするサイトを作らなければいけなかった。

そこで、JavaScriptの仕様を統一しようということで、EcmaScriptという言語仕様が登場した。

これの登場によって、各ブラウザベンダ間での実装がまぁまぁ同じになって、昔より格段と作りやすくなった。(マシになったというだけで、今も辛いのは変わっていない)

今でも他の言語とは違ってJavaScriptでは、仕様と実装が乖離していることが多い。そのためEcmaScriptのことを意識しないと使いにくい。

たとえばPythonでは、PEPが言語仕様で、CPythonやPyPyが言語実装であり、あんまり実装や仕様のことを考えなくてもCPythonがかなり支配的なので「Pythonとはこういうもの」という理解だけでも、そんなに混乱することはない。*1 *2

一方JavaScriptでは、IESafariChromeFirefoxJavaScriptの動きが異なっており、日本ではそのすべてに対応しないといけないことが多いので、EcmaScriptを意識しないと「JavaScriptとはなんやねん」って感じになってしまう。

つまりEcmaScriptという言語仕様があるという概念を理解するのは、ものすごくだいじ。

EcmaScriptの現在

現在でも各JavaScriptエンジン開発者は、このEcmaScriptという言語仕様をもとにおのおののエンジンを開発している。

EcmaScriptは、現在バージョン8まで仕様が決められており、これはES8とかES2017と呼ばれている。現在はES2019が策定中。

ES2019については→GitHub - tc39/ecma262: Status, process, and documents for ECMA262

ES2018についてはこっちのブランチを参照→GitHub - tc39/ecma262 at es2018

(ES8(ES2017)の実際の言語仕様についてはStandard ECMA-262を参照)

2018年3月現在の主要ブラウザでは、

ブラウザ バージョン 備考
Chrome だいたいES8(ES2017)まで
Firefox だいたいES7(ES2016)まで
Safari だいたいES7(ES2016)まで
Edge だいたいES6(ES2015)まで
IE 11 ほとんどES5まで IE11は2025年10月までサポートされる💢

のようになっている。*3

※ここから引用したよ

ECMAScript 2016+ compatibility table

JavaScriptエンジンの現在

各ブラウザベンダは、それぞれ別々のJavaScriptエンジンを使って、開発者にJavaScriptの実行環境を提供している。

ブラウザ エンジン リファレンス
Chrome V8 JavaScript Engine GitHub - v8/v8: The official mirror of the V8 Git repository
Firefox SpiderMonkey SpiderMonkey - Mozilla | MDN
Safari JavaScriptCore https://github.com/WebKit/webkit

こんな感じでまあ色々ある。

なので、前述した通りそれぞれJavaScriptの実装状況が全く違う。

つまりこうした状況で、自分たちが各々の実装を見極めて使える使えないを判定しなければいけない。

これが大変なので、polyfill(様々なブラウザに対応するためのプラグインという概念)や、後述するBabelというトランスパイラが出現することになる。

Nodeの登場によるJavaScriptの変革

話は過去に戻る。

あるとき、Node(のーど)というJavaScriptの実装が登場した。

それまでJavaScriptというのは、ブラウザベンダが実装するものであって、ぼくたちがターミナルでJavaScriptを触るという機会はほとんどなかった。*4

それがNodeというJavaScript実装が登場したことによりターミナル上で

$ node foo.js
Hello World!

のようにしてJavaScriptを実行できるようになった。

これがJavaScriptのひとつの転換期で、Node全盛の時代が始まる。そして現在もNode全盛の時代である。

npmというのは、Node Package Managerのことで、Nodeで動かすことを目的として作られたJavaScriptのライブラリを管理するためのツールである。

npmはNodeに同梱されている。

ちなみにNodeで使われているJavaScriptエンジンは、前述のV8 JavaScript Engineである。(追記: 2018/05/02 Node v10からはV8に依存しなくなったので、好きにエンジンを切り替えられるらしいです)

JavaScriptビルド時代

nodeやnpmを使用してJavaScriptの開発をするようにまで人類が成長した近代。

人類は他の言語でも使われているビルドという概念を、JavaScriptに導入したのであった。

それがGruntGulpである。タスクランナーと呼ばれている。

書いたコードを、製品として出すときに、インデントなどを削ったりしてコードのサイズを小さくしたりするために使われたり、JavaScriptでテストを実行するときにも使われた。

現在ではnpmのpackage.jsonファイルに若干存在を食われており、あまり新規で使うことはないが、まだ使われてはいる。

↓こういうかんじでつかわれてた

var gulp = require('gulp');
var browserify = require('gulp-browserify');
 
// Basic usage 
gulp.task('scripts', function() {
    // Single entry point to browserify 
    gulp.src('src/js/app.js')
        .pipe(browserify({
          insertGlobals : true,
          debug : !gulp.env.production
        }))
        .pipe(gulp.dest('./build/js'))
});

トランスパイルして古いバージョンはどんどん殺していく現代

あらゆるソフトウェアで、バージョン違い、つまり後方互換性とはものすごくめんどくさい問題だった。

サービスが広まれば広まるほど、古いバージョンを使っている人の数が増えるので、これまでは「古いバージョンをどうサポートするか」ということに主眼が置かれていた。

現在ではアップデートは自動で行われるようになり、それでもアップデートしないやつはもう知らん、という方針を人類が選択したことで、開発者が新機能を使って開発することができるようになった。

特にOS周りでその動きが顕著である。

一方JavaScriptでは、IEのサポート終了期間が長すぎるので、気軽に自動でJavaScriptをアップデートとかできなかった。

そこで誰かが「古い言語仕様にしか対応してないブラウザに対応せざるを得ないなら、新しい言語仕様で書かれたコードを、古い言語仕様のコードに変換すればよくね?」という天才の発想を思いつき、それをトランスパイルという。

このトランスパイルするやつの1つがBabel

BabelはおもにES6(ES2015)のJavaScriptをES5仕様のJavaScriptに変換する。

もっと新しい言語仕様の実装を使いたい場合はpresetというのを含めると良い。ちなみにenvというpresetをつけると最新になる(ES2017 preset · Babel)

他にもbabel-polyfill(Polyfill · Babel)などで、クロスブラウザ問題(ブラウザ間のJavaScriptの実装の違いの問題)を解決する。

そんなかんじでした。

その他

npmと bower について

NodeはもともとサーバーサイドでもJavaScript使おうぜという発想で作られたものだった。

なのでnpmは、サーバーサイドで使うJavaScriptライブラリを格納するためのものだった。いわゆるパッケージマネージャ。

bowerは、npmがサーバーサイドのものなんだから、こっちはクライアントサイドのものを入れようぜという思想のもと作られたパッケージマネージャであった。

でも、

( ^o^)<クライアントに関するライブラリはbowerで管理するぞ〜!bowerはnpm使ってインストールするぞ〜

( ˘⊖˘) 。o(待てよ、なんで敢えて分けて管理する必要があるんだ??npmで全部管理すればよくね?)

|npm|┗(☋` )┓三

( ◠‿◠ )☛ そこに気付いたか。bowerには死んでもらおう

▂▅▇█▓▒░('ω')░▒▓█▇▅▂うわあああああああああああ

ということになった。現在ではbowerは技術的負債として各々のプロジェクトに眠っている存在である。

npmとYarn

Yarnはnpmの上位互換。

npmでのnode_modules下にある、重複したライブラリを1つにしたり、新しくJavaScriptライブラリをinstallする際にキャッシュがあればそこからインストールするというように使われる。

基本yarnを使った方がいいけどまだ主流はnpmで、yarn自体もnpmでインストールする上Facebookが牛耳っているし、みんなよくわかってないので、あまり魅力を感じられていない。

[追記]コメントで指摘がありましたが、npmからじゃなくてMacだとHomebrew、WindowsだとChocolateyでやるっぽいです。昔からこうだったっけ……? → インストール | Yarn

 

全然広まらないので、そのうちyarnの機能がnpmに取り込まれるのでは説がぼくの中で結構ある。

よくわからなかったらとりあえずnpm使っとけばいい。ぼくはyarn使ってる。

webpackとは

GruntGulpなどのタスクランナーの役割に似ているが、こちらはブラウザ用にビルドするために特化したもの。

JavaScript以外にも、CSS、Sass、HTML、jpgなど、ほぼすべてのものをモジュール化して一つのJavaScriptファイルを生成するもの。これをバンドルファイルっていう。

設定をwebpack.config.jsに書くだけでよく、今は基本これ使っとけばいい。

webpack-dev-serverと組み合わせて使うとホットリロードとかされて開発しやすい。

ぼくが思ってること

JavaScriptは他の主要な言語と違ってつらみが多い。

たとえば以前、leftpadというライブラリがnpmから消されたことによって、JavaScript界隈が大混乱に陥ったことがある。

qz.com

postd.cc

いままでJavaScriptはつらすぎたので、それをなくす動きがようやく始まったよという感じがしてる。

IE対応は早めに切り捨てないとそのうち辛くなるので、早めに「IEの場合は機能限定をする」とか考えないといけないなとも思った。

でもV8 JavaScript Engineを作ってる人がWebAssemblyすごくいいよ!とか言ってるので、そのうちJavaScriptが死ぬ世界が来ても全然おかしくないと思う。

この適当な解説が、誰かの何かの役にたてば幸いです🐹 間違いとかあれば指摘ほしいです。

*1:ただしPEPのすべてが言語仕様というわけではない

*2:だからPythonはいい、JSはダメという話ではないです

*3:IE使用者が4人に1人を占めている日本ではIE対応をしないといけないことが多く、かなりつらいことがわかる。

*4:らしい。ぼくがJSに触れたときには既にNodeがあった

iPhone5(iOS8.3)+SafariのときだけReferenceError: Can't find variable: webpackJsonpとか言われてwebpack-dev-serverが動かないときにやること

Kind of the following error.

f:id:haruharu1:20180214183714p:plain

To solve it, update your webpack-dev-server NOW!!

github.com

I wish I didn't care devices worked on older-version iOS.