macOS High Sierraにしたらhomebrewが使えなくなった

環境

macOS High Sierra 10.13.1

事象

正確に言うと以下のようなメッセージが表示されてbrew installが使えなくなりました。

xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun

解決法

上記のエラーメッセージで検索すると、gitが使えない!という内容の記事がたくさん見つかりました。

Mac OS Sierraにしたらgitコマンド、ターミナル上にエラーが出てしまった。 - Qiita

El Capitanにしたらgitコマンド(CUI)が動かなくなった。 - Qiita

上記の記事を参考に、xcode-selectコマンドを実行することで無事解決できました。

$ xcode-select --install

上のコマンドは何?

Xcode Command Line Toolsをインストールするもの。 このツールがあることでgitgccmakeといったコマンドが使えるようになります。

Xcode本体に付属していますが、iOSアプリ開発をしないならCLIを単体で入れた方が数GB容量を節約できます。

OSがアップデートされるたびにCLIも入れ直す必要があるみたいですね。

なぜbrew installが使えなくなったのか?

brewコマンド自体は自分でバイナリインストールしたはずなのでCLIは一見関係なさそうなのが心に引っかかりました。

homebrewの仕組みを調べて見たところ、installの内部ではmake installを実行しているようでCLIに入っているmakeが使えないことが原因だったみたいです。

Homebrew — macOS 用パッケージマネージャー

Homebrew の formula はシンプルな Ruby スクリプトです:

class Wget < Formula
  homepage "https://www.gnu.org/software/wget/"
  url "https://ftp.gnu.org/gnu/wget/wget-1.15.tar.gz"
  sha256 "52126be8cf1bddd7536886e74c053ad7d0ed2aa89b4b630f76785bac21695fcd"

  def install
    system "./configure", "--prefix=#{prefix}"
    system "make", "install"
  end
end

最後に:CLIのバージョンを確認する方法

brew --config出力結果のCLIを参照します。

$ brew --config
HOMEBREW_VERSION: 1.3.9
ORIGIN: https://github.com/Homebrew/brew
HEAD: 4f5e938a5dbe049e05dea19495b6547acc5c5b5b
Last commit: 4 days ago
Core tap ORIGIN: https://github.com/Homebrew/homebrew-core
Core tap HEAD: 2dfcf690f03253ad124dc1c8dae46ef0e82c98c6
Core tap last commit: 5 hours ago
HOMEBREW_PREFIX: /usr/local
CPU: quad-core 64-bit broadwell
Homebrew Ruby: 2.3.3 => /usr/local/Homebrew/Library/Homebrew/vendor/portable-ruby/2.3.3/bin/ruby
Clang: 9.0 build 900
Git: 2.13.6 => /Library/Developer/CommandLineTools/usr/bin/git
Curl: 7.54.0 => /usr/bin/curl
Perl: /usr/bin/perl
Python: /usr/local/opt/python/libexec/bin/python => /usr/local/Cellar/python/2.7.14/Frameworks/Python.framework/Versions/2.7/bin/python2.7
Ruby: /Users/manami/.rbenv/shims/ruby => /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/bin/ruby
Java: 1.8.0_121
macOS: 10.13.1-x86_64
Xcode: 9.1
CLT: 9.1.0.0.1.1508540944
X11: N/A

このトラブルを通じてGNU Makeに興味が出てきたのでさらに勉強してみようー

pt-online-schema-changeでrebuild_constraint時に"child_table has no foreign key constraints referencing _parent_table_old"という警告が出る

事象

pt-online-schema-change 3.0 でALTER対象のテーブルを参照する外部キーが2つ以上ある子テーブルについて、--alter-foreign-keys-method=rebuild_constraintで外部キーの紐付けを直そうとすると、2つ目以降の外部キーに対して表題の警告が出る。

原因

参照のチェック→リビルドの処理フローを制御するループの不備によるバグ。

  • 子テーブルのリストがユニークになっておらず、参照の数だけ子テーブルのリストが膨らんでいる(@$child_tables)
  • 参照の数分警告のチェックが走る
  • 子テーブル1つにつき、全ての外部キー制約(@constraint)のリビルドを行なっている

https://raw.githubusercontent.com/percona/percona-toolkit/3.0/bin/pt-online-schema-change

   CHILD_TABLE:
   foreach my $child_tbl ( @$child_tables ) {
      my $table_def = $tp->get_create_table(
         $cxn->dbh(),
         $child_tbl->{db},
         $child_tbl->{tbl},
      );
      my @constraints = $table_def =~ m/$constraint/g;
      if ( !@constraints ) {
         warn ts("$child_tbl->{name} has no foreign key "
            . "constraints referencing $old_tbl->{name}.\n");
         next CHILD_TABLE;
      }

      my @rebuilt_constraints;
      foreach my $constraint ( @constraints ) {
         PTDEBUG && _d('Rebuilding fk constraint:', $constraint);
     . . .

子テーブルのリストを作るクエリ

   my $sql = "SELECT table_schema, table_name "
           . "FROM information_schema.key_column_usage "
           . "WHERE referenced_table_schema='$tbl->{db}' "
           . "AND referenced_table_name='$tbl->{tbl}'";

対応

処理に影響ないので無視しても良いが、修正するなら下のような感じ?

  • 子テーブルのリストをユニークにする
  • 同じ要素について2周目以降はスキップする
  • 制約のリビルドは最初に見つけた一件のみに対して行うようにする

2017/10/18 追記

バグ報告しました bugs.launchpad.net

The server quit without updating PID fileというエラーが出て、ローカルmysqlサーバが起動しない

qiita.com

この記事などにあるように、/usr/local/var/mysql以下をchownしたものの、同じエラーが出続けていました。

$ sudo chown -R mnmandahalf /usr/local/var/mysql/
Password:
$ mysql.server start
Starting MySQL
... ERROR! The server quit without updating PID file (/usr/local/var/mysql/Mnmandahalfs-MacBook-Pro.local.pid).

煮詰まったので何気なくpidファイルを作って、再度サーバーを立ち上げてみたところ、、、

$ touch /usr/local/var/mysql/Manamis-MacBook-Pro.local.pid
$ mysql.server start
Starting MySQL
.rm: /tmp/mysql.sock: Permission denied
2017-10-02T14:50:19.6NZ mysqld_safe Fatal error: Can't remove the socket file:
/tmp/mysql.sock.
Please remove the file manually and start /usr/local/Cellar/mysql/5.7.19/bin/mysqld_safe again;
mysqld daemon not started
 ERROR! The server quit without updating PID file (/usr/local/var/mysql/Mnmandahalfs-MacBook-Pro.local.pid).

エラーメッセージが変わった。 /tmp/mysql.sockの権限を確認したところ、所有ユーザーがrootになっていました。

$ ls -la /tmp/mysql.sock
-rw-r--r--  1 root  wheel  0 10  2 22:31 /tmp/mysql.sock

メッセージの通りにmysql.sockを削除し、mysqld_safeを実行。

$ sudo rm /tmp/mysql.sock
$ /usr/local/Cellar/mysql/5.7.19/bin/mysqld_safe
2017-10-02T14:51:39.6NZ mysqld_safe Logging to '/usr/local/var/mysql/Mnmandahalfs-MacBook-Pro.local.err'.
2017-10-02T14:51:40.6NZ mysqld_safe Starting mysqld daemon with databases from /usr/local/var/mysql

別プロセスからmysql.sockの権限を確認。

$ ls -la /tmp/mysql.sock
 srwxrwxrwx  1 mnmandahalf  wheel  0 10  2 23:52 /tmp/mysql.sock

多分この権限と/usr/local/var/mysql/以下の権限を最初に揃えておけばよかった?

mysqldも立ち上がった模様。

$ ps aux | grep mysql
mnmandahalf           72116   0.0  0.0  2435000   1228 s004  R+   11:55PM   0:00.01 grep mysql
mnmandahalf           72096   0.0  2.1  2836108 177372   ??  S    11:51PM   0:00.42 /usr/local/Cellar/mysql/5.7.19/bin/mysqld --
basedir=/usr/local/Cellar/mysql/5.7.19 --datadir=/usr/local/var/mysql --plugin-dir=/usr/local/Cellar/mysql/5.7.19/lib/plugin --
log-error=Mnmandahalfs-MacBook-Pro.local.err --pid-file=Mnmandahalfs-MacBook-Pro.local.pid
manami           72024   0.0  0.0  2438664   1972   ??  S    11:51PM   0:00.03 /bin/sh 
/usr/local/Cellar/mysql/5.7.19/bin/mysqld_safe

ログインできました。

$ mysql -u root -p
Enter password: 

Railsのcheck_boxのチェック時、アンチェック時にどんな値がサーバに送られるか

1. デフォルト

<%= f.check_box :remember_me %>

HTML

<input name="session[remember_me]" type="hidden" value="0”>
<input type="checkbox" value="1" name="session[remember_me]" id="session_remember_me”>

チェックon時のparameters

parameters: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
  email: foo@bar.co.jp
  password: foobar
  remember_me: '1'

チェックoff時のparameters

parameters: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
email: foo@bar.co.jp
password: foobar
remember_me: '0'

2. true / false

<%= f.check_box :remember_me, {} , true, false %>

HTML

<input type="checkbox" value="true" name="session[remember_me]" id="session_remember_me”>

チェックon時のparameters

parameters: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
  email: foo@bar.co.jp
  password: foobar
  remember_me: 'true'

チェックoff時のparameters

parameters: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
  email: foo@bar.co.jp
  password: foobar

3. 1 / nil

<%= f.check_box :remember_me, {} , 1, nil %>

HTML

<input type="checkbox" value="1" name="session[remember_me]" id="session_remember_me”>

チェックon時のparameters

parameters: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
  email: foo@bar.co.jp
  password: foobar
  remember_me: '1'

チェックoff時のparameters

parameters: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
  email: foo@bar.co.jp
  password: foobar

4. "true", "false"

<%= f.check_box :remember_me, {} , "true", "false" %>

HTML

<input name="session[remember_me]" type="hidden" value="false”>
<input type="checkbox" value="true" name="session[remember_me]" id="session_remember_me”>

チェックon時のparameters

parameters: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
  email: foo@bar.co.jp
  password: foobar
  remember_me: 'true'

チェックoff時のparameters

parameters: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
  email: foo@bar.co.jp
  password: foobar
  remember_me: 'false'

まとめ

  • Railsのcheckboxヘルパーは、文字列の値しか送らない(故にtrue / falseを送れない)

  • 値を指定しない場合は、チェックonで'1'、チェックoffで'0'が送られる

  • 文字列以外の値を指定した場合は、 チェックon時のHTMLのみが生成され、値は文字列変換されるチェックoff時の値はparameterに送られない

  • 上記の性質を利用して、有意味な区分値を埋め込んで送信したり、オンオフをnil?やpresent?などでシンプルで判定するためにあえてチェックoffの値を送らないように設定するといった工夫ができる

【学習メモ】色の見え方と液晶の仕組み

目次

1. 色が見える仕組み

2. 液晶ディスプレイの仕組み

 

1. 色が見える仕組み

まず大前提として、人の目には、明暗を感知する桿体細胞と、色を感知する錐体細胞というものがある。

この錐体細胞を構成するタンパク質の構造が3種類あり、異なる波長の光に反応する。

この3種類が、

R:560nm 赤錐体

G:530nm 緑錐体

B:430nm 青錐体

なのである。

人間の色覚は、この3種類の光を異なる明るさで混合したものを感知することでよって成り立っている。

 

2. 液晶ディスプレイの仕組み

液晶とは、液体と固体の性質を兼ね備えた物質のことである。

液晶には、一定の電圧を加えると分子が規則的に並ぶという特徴がある。

そして、規則的に並んだ部分は光を通さなくなるのである。

画面の明暗は、画素(画像を表示する最小単位)ごとに光の透過度合を変えることで実現している。

色については、①白色光を3色のカラーフィルターに通す場合と、②3色のLEDを光源とする場合がある。

ざっくり言うと次のような順番で光を通す。

 

①カラーフィルター方式

[バックライト(白色光)→偏光板→液晶→偏光板→カラーフィルター]

光の明暗は液晶の配列を調整することによって透過度合いを変えて実現する。

 

②カラーフィルターレス方式

[LED(3色)→偏光板→液晶→偏光板]

光の明暗はLEDが調整するため、液晶の配列は光を通す・通さないのみ。

 

カラーフィルター方式については、1画素につきRGB3色のカラーフィルターを配置するが、カラーフィルターレス方式は1画素につきRGBRGBRGB・・・という配置が可能となるため、よりなめらかな表示となる。