iriya-ufo's blog

Curiosity was simply the first derivative of knowledge.

<unknown>:0: Error: The SDK ‘MacOSX10.9.sdk’ Does Not Support Swift

Xcode6-beta6 にて swift をコマンドラインから起動するとタイトルの通りのエラーがでます。

<unknown>:0: error: the SDK 'MacOSX10.9.sdk' does not support Swift

MacOSX 10.9 というのは Mavericks ですね。どうやら最新の Xcode は古い sdk はサポート対象外ということで起動すらできません。さすが Apple 切り捨て方が潔い。さてどうやって起動するかというと、Xcode6 に付随している最新の sdk を使うように swift の起動オプションに渡してあげたら大丈夫です。以下コマンドです。

$ /Applications/Xcode6-Beta6.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -target x86_64-apple-macosx10.9 -sdk /Applications/Xcode6-Beta6.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk

また Xcode のバージョンアップをした人は「Swift をとりあえず実行するまでの手順」の「コマンドラインから実行する」で雑多な設定をやってあげるといいでしょう。

Xcode で作ったプロジェクトを削除する方法

練習がてら適当にプロジェクトを作成するといっぱい溜まってくるのでいらないものは消してすっきりしたくなる時があるかと思います。Xcode で作ったプロジェクトを完全削除するには以下のようにすればよいです。

  • Finder で、作成したプロジェクトディレクトリを消す
  • Xcode を起動して「Window」=>「Organizer」でデバイスを消す

以上です。

Gauche のユーザーリファレンスを読む

Gauche のリファレンス読むのにはいくつか方法があって、Emacs で el いれて読みだすとか info 入れるとかありますけど、一番簡単な方法はこれでしょう。 Chrome 使ってる人向けですが、設定にいくと「検索エンジンの設定」があるのでそちらで以下のようにします。

新しい検索エンジンを追加 => Gauche(任意)
キーワード => gosh(任意)
検索キーワードの代わりに => http://practical-scheme.net/gauche/man/?l=jp&p=%s
アドレスバーに「gosh」とタイプした後に tab 打ち込むとリファレンスが検索できます。便利!

なお、この記事はこれの劣化パクリです。

「良いコードを書く技術」読了

良いプログラマであるならば良いコードに対する知見があるはずです。初心者の間は何が良いコードで何が悪いコードなのか分からないことが多く、また分かったとしてもどうやって良いコードにリファクタリングするのか不明瞭な所が多いです。本書では具体事例を上げて良いコードとは何かについて語られています。

まず良いコードについての定義から入ります。

  • 保守性が高い
  • 効率的に動作する
  • 正確に動作する
  • 無駄な部分がない

これら条件を達成するために、変数名の付け方から始まり抽象化やメタプログラミングまで幅広く扱っています。

以下各章の内容をざっくりとまとめてみました。

名前付け

変数名、メソッド名、クラス名、様々な場面において名前をつける過程が発生します。よくあるコーディング規約に乗りつつ、長すぎない、短すぎない、処理の意図を反映した名前などをつけることが大事だと言われています。

スコープ

スコープを意識して影響範囲を小さくするようにします。言語によって仕様が異なるし、変数なのかメソッドなのかクラスなのかによってもスコープ範囲は変化するので日頃から意識してコードを書く必要があります。

コードの分割

コードの一部を分けるということはよくある作業ですが、単純にコードが長いから分けるのではなく可読性などを考えた上で分けることが大事です。コード分割をする際の考え方として大きく2つあると書かれています。一つはボトムアップ形式でもう一つはトップダウン形式です。 ボトムアップ形式ではまずベタに書いてみてその後に分割できそうな箇所を洗い出すというやり方で、トップダウンは予め想定される必要なメソッドやクラスなどを分割してその後実装に入るというやり方です。どちらも一長一短があるので両方取り入れて開発するのがいいと思います。

コードの集約

先ほどはコードの分割でしたが今度はコードを集める、です。同じような処理があるコードは集約しようという考えです。メソッドでまとめる、継承でまとめる、オブジェクトでまとめる、定数でまとめる、などの方法があります。

コードのパフォーマンス

若干高度な内容だと思いました。計算量を意識してコードを読む、クラスの選択によるパフォーマンスの変化、ライブラリの使い方による変化、などなど。パフォーマンスに関してはこれだけで本一冊書けそうなくらい奥の深い分野ですね。

ユニットテスト

テストは大事だよね、っていう話しです。割愛。

抽象化

コードの集約と通ずるところがありますが、単にまとめるという意味に留まらず、突然の変更にも柔軟に対応できるような設計をすることが抽象化において大事なことだと思います。本書では「画像ファイルの一覧を表示するWebアプリケーション」というお題で実際にベタなコードから始まり抽象化をしていくコードが載ってあります。

メタプログラミング

コードを自動生成するコードなどではメタプログラミングが必須です。本書では「ExcelによるDSL」で具体的なコードがあります。

フレームワークを作ろう

割愛

つまり、良いコードとは何か?

普段意識して読んだり書いたりしている人は自ずと良いコードになっていきますが、よく考えずにただコーディングしているだけではなかなか良いコードは書けないと思います。本書を読むとどう思考してどこに注意すれば良いコードが書けるのかの手助けになります。ぜひ読んでみるといいでしょう。

「グーグル ネット覇者の真実」読了

グーグルネット覇者の真実を読みました。 ほとんど読み飛ばしました。気になった点だけ引用させて頂きます。

真の意味での失敗はひとつしかなく、それは野心的な課題に挑戦しないことだった。「たとえ失敗したとしても、完全に失敗するようなことはめったにない」と彼は言う。必ず何らかの成果を得られるはずだと。「皆、それがわかっていないんだ。」この原則がペイジの念頭を離れることはなかった。
彼はミーティング終了直前にある質問をした。「事業規模はどれくらいになると思うかね?」「100億ドルですね。」とペイジは答えた。まさか本気で時価総額100億ドルの企業になると考えているわけではないだろうね、とドーアは言った。すでに頭の中ではグーグルの時価総額は最高10億ドル程度までは行くだろうと計算していた。「いえ、本気でそう考えています。」とペイジは言った。「それに100億というのは時価総額ではありません。収益です。」
セルフサービス型のシステムを構築すれば、数千社もの小規模な広告主に広告を提供できるだけでなく、必要経費を最小限に抑えて、広告料金もかなり低く設定できる。
ユーザーが Gmail を実際に使いはじめると、もっと深刻な問題も表面化した。彼らはメールに書いた文章の横にその内容と関連しているとしか思えない広告が表示されるのを見てショックを受けた。まるでメールを書いているところをグーグルに背後からのぞき込まれたかのように感じたのだ。
グーグルのエンジニアたちは自分たちのメールは永遠に保存して「ほしい」と考えていたし、ウェブを通じて全世界が接続された時代には、情報はSFチックな未来型の貸し金庫のような場所にプロの手で安全の保存されるのが理想だと信じていたからだ。彼らにすれば、これが個人情報保護に対する懸念を招いているのは筋の通らない話しだった。彼らは機械を信用していたし、彼ら自身の動機も純粋だった。だからユーザーは彼らをもっと信頼すべきべきだと。

細かい話しまで書かれていたので気になる方は一度読んでみるといいと思います。

Don’t be evil.

「アインシュタインの教育観」読了

教える能力で大事な事

「教える能力というのは面白く教える事である。どんな抽象的な教材でも、それが生徒の心の琴線に共鳴を起こさせるようにし、好奇心をいつも活かしておかねばならない。」

数学嫌いの生徒は主に教師のせいである、と言っています。学校教育の数学は確かに嫌いな子はどうしようもないくらい嫌いです。だけどそれは原因が教師側にあると言っています。好奇心を持たせる工夫をさせることが必要ですね。例えば野外に出て建物や自然物などの高さを測る方法を考えるとか、そうすれば具体的な行動体験と三角関数が結び付けられますね。

教育事業を救う方法

アインシュタインは一貫して体験を重視しているようです。

もっと眼に浮かぶようにする。 できれば知識が体験になければならない。

動画や画像などを使えば実験を追体験できます。それに視覚から強い刺激で得た情報はなかなか忘れにくいです。できれば実験をしてあげるとよいのでしょうね。 また知識は単に教室で教科書を開いて詰め込まれたものではなく、体験として得よということでしょう。

女子教育について

性差はある。 キュリー夫人のような例は特殊である。 単に素質が増し智能が増すという量的な前提から、天才が増すという質的の向上を結論づけるのは少し無理ではないか。

話題は女子教育に転じます。男性と女性においてどうしようもない性差があるとアインシュタインは言っています。これがどのようなものかという細かい言及はありませんが。 また天才を生み出すということにおいても量的な問題から解決するものではないとも言っています。天才という存在は本当に異常なんでしょうね。

Swift をインタラクティブに実行しながら勉強しよう (関数編)

Swift はコンパイラ言語でありながら、インタプリタとしてスクリプトを実行することも可能で、対話実行環境(REPL(英語版))も用意されている。Swift と同時に発表された Xcode バージョン 6 では、コードの実行結果をグラフィカルに確認しながら開発できる Playgrounds が実装された。

Wikipedia より引用

説明の通り Swift はインタラクティブに実行することが可能となっています。Playgrounds を使ってもいいのですが、もっとお手軽なシェルから実行して遊んでみましょう。

環境構築

まず以下を参考にしてコマンドラインから実行できる環境を整えましょう。

Swift をとりあえず実行するまでの手順

Hellow, World

それではさっそく Hellow, World しましょう。適当な場所に拡張子 .swift でファイルを作り以下の一行を書きます。

1
println(Hello World)

実行してみましょう。-i オプションをつけるとバイナリファイルを生成せずに直接実行されます。

$ swift -i sample.swift
Hello, world

できました!なんと簡単なことか!

関数を試す

このまま続けましょう。いきなりですが関数を書きます。

1
2
3
func doNothing() {
}
doNothing()

実行しても何もおきませんね。なので少し変えます。

1
2
3
func doNothing() {
}
var nothing = doNothing()

むむむ warning が出ました。

1
2
3
4
5
6
7
sample.swift:3:5: warning: variable 'nothing' inferred to have type '()', which may be unexpected
var nothing = doNothing()
    ^
sample.swift:3:5: note: add an explicit type annotation to silence this warning
var nothing = doNothing()
    ^
           : ()

関数の返り値を nothing 変数に代入しようとしたのですがダメみたいです。warning によると関数は空のタプル '()' を返してるようですね。これを明示的に宣言する必要があるみたいです。このようにします。

1
2
3
func doNothing() {
}
var foo: () = doNothing()

これで warning が消えました。swift では var で変数宣言をして foo を変数名として : コロンの後に型を書くというやり方をします。また以下も動作します。

1
2
3
func doNothing() {
}
var foo: Void = doNothing()

それでは試しに文字列を返す関数を書いてみます。

1
2
3
4
func retString() {
    return "Hi"
}
var foo: String = retString()

あれ、今度はエラーが出ました。

1
2
3
4
5
6
sample.swift:4:19: error: '()' is not convertible to 'String'
var foo: String = retString()
                  ^
sample.swift:2:12: error: type '()' does not conform to protocol 'StringLiteralConvertible'
    return "Hi"
           ^

なるほど retString 関数は文字列を返して欲しかったのに依然としてタプルを返していますね、そしてそれを文字列に変換できないという旨のエラーです。関数の返り値に Void 以外を返す場合、型を宣言する必要があるようですね。こうしましょう。

1
2
3
4
func retString() -> String {
    return "Hi"
}
var foo: String = retString()

やりました!エラーが消えました。ついでに引数も渡してみましょうかね。

1
2
3
4
func retString(str) -> String {
    return "Hi " + str
}
var foo: String = retString("How's it going?")

またエラー発生です。

1
2
3
sample.swift:1:16: error: use of undeclared type 'str'
func retString(str) -> String {
               ^~~

ほうほう、ここも型宣言が必要なのですか。こうすれば通るかな?

1
2
3
4
5
func retString(str: String) -> String {
    return "Hi " + str
}
var foo: String = retString("How's it going?")
println(foo)

やりました!関数を書くには、返り値および引数の型宣言が大切なようですね。

以上 Swift の関数でした。

参考

1. Learn Swift by running Scripts

Swift をとりあえず実行するまでの手順

WWDC2014 にて発表された Apple の新言語 Swift が話題になっています。これから iOS アプリを開発するなら間違いなく Swift が使えるようになる必要がありますね。ここでは Swift に関する情報のまとめと簡単なプログラムを Swift で実行するまでの流れを書きたいと思います。

情報まとめ

まず最初にブックマークしておくべきサイト達です。たびたび覗きにくることになるでしょう。

Xcode で実行する

Swift を実行するには Xcode 6 beta が必要です。コマンドラインから swift を実行する方法は後述します。まずここからダウンロードしてください。Xcode 6 beta のインストールにはデベロッパープログラムに入らないといけないので事前に登録しておきましょう。頻繁にアップデートされていくと思うので時々チェックするといいでしょう。ちなみに Xcode4 から Xcode5 にアップデートした際にアプリケーション一覧で Developer からコンポーネントがいくつかなくなっていると思います。インストール場所が /Developer から /Applications に変更されたためです。LaunchPad に表示されるのもうっとおしいので削除しましょう。削除の仕方はこちらから。

脱線したので戻します。先ほどダウンロードしてきた Xcode 6 beta をインストールしましょう。いつものように dmg ファイルを起動して Applications フォルダーに移すだけです。インストールが終わったら早速起動してみましょう。起動したら Welcome 画面が出てくるのでおもむろに閉じます。

まず File > New > Project を選択し、iOS の「Single View Application」を選択して、Next ボタンを押します。そして Project 名の入力と Language に Swift を選択して Next ボタンで進みます。保存場所を聞かれるので任意の場所を決めます。

画面が立ち上がりますので ViewController.swift ファイルの中の override func viewDidLoad() の場所に println("Hello, World") を記述します。これで実行するとシミュレータ上で Hellow, World が表示されます。

以上駆け足で Xcode で Hello, World をやってみました。実行まで結構面倒くさいですね。でも安心してください Swift はコンパイラプログラミング言語だけど、Xcode の Playgrounds の上やターミナルでインタラクティブにデバッグする事が可能になっています。Playgrounds のやり方は割愛させて頂きますが、コマンドラインから Swift をインタラクティブに行う方法を述べます。

コマンドラインから実行する

Swift REPL は以下のようにして実行できます。(Xcode のインストールが必要)

$ /Applications/Xcode6-Beta4.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift
Welcome to Swift!  Type :help for assistance.
1>  

毎回打つのはめんどくさいのでシェルのエイリアスに登録しておくとよいでしょう。

また xcrun というコマンドを使うと Xcode 周りの面倒をいい感じに見てくれるらしいので Swift REPL を使うときはセットでの使用をオススメします。 使い方は簡単で以下のようにするだけです。

$ xcrun swift

もしエラーが出るような場合 Xcode の PATH が見つけられていないので、下記のようにして正しく設定します。

$ sudo xcode-select -switch /Applications/Xcode6-Beta.app/Contents/Developer

これでコマンド引数にファイルを与えてあげるとバイナリーが生成されるようなのでそいつを直接実行してやるといいですね。

以上コマンドラインツールからの実行でした。

Mavericks にアップグレードしたらターミナルが落ちた

今更ですが Lion から Mavericks にアップグレードしました。OS のアップグレードは色々トラブルが起こるのであまりしたくないのですが、流行りについていかないのもなぁと思いアップグレードを実行しました。

そしたらターミナルが起動しなくなりました。一瞬起動したような感じがするのですが、すぐにウィンドウが消えます。標準のターミナルでも iTerm でも同様の症状なので zsh 周りの問題だろうと考え、一度ログインシェルを /bin/bash へと変更しました。変更の仕方は「システム環境設定」=>「ユーザーとグループ」にて変更するための鍵をクリックし、ログインユーザーを右クリックで詳細オプションを見ます。そこに見えるログインシェルをひとまず /bin/bash などに変更すればターミナルが使えるようになります。

色々いじったので順番は定かではないのですが、以下のようにしたら直りました。

まず Xcode を AppStore 経由でアップグレードします。終わったらターミナルからコマンドラインツールをインストールします。

$ xcode-select --install

ここで zsh のチェックをすると、以下のようなエラーでした。

$ /usr/local/bin/zsh --version
dyld: Library not loaded: /usr/local/lib/libgdbm.4.dylib
  Referenced from: /usr/local/bin/zsh
  Reason: image not found

brew 周りが怪しいので掃除します。

$ brew update
$ brew outdated
$ brew upgrade foobar # 気になるものだけアップグレード
$ brew doctor # エラーを潰す

gdbm と pcre 周りの link を再設定します。

$ brew unlink gdbm && brew link gdbm
$ brew unlink pcre && brew link pcre

ここまででひとまず /usr/local/bin/zsh でログインできるようなりました。ちなみにログインシェルの変更は以下のようにします。

$ chpass -s /usr/local/bin/zsh
$ chpass # 確認

またログインシェルは先ほどのユーザーとグループの詳細オプションからも確認できます。

そしてなぜか rbenv のコマンドが見つからないぞ、と怒られたので rbenv は brew で再インストールしたら直りました。

これで一件大丈夫なように思いましたが、その他何か挙動がおかしい気がします。調べてみたところ、Marvericks へのアップグレードで brew へのパスがおかしくなっているようです。以下のようにして全て relink しました。

$ brew list | xargs brew unlink
$ brew list | xargs brew link

以下のものについては --force 付きで強制的に relink しました。 (brew doctor で keg-only だから unlink しろと怒られます)

gettext
libffi
openssl
ossp-uuid
readline

また zsh のパスが重複してることに気づいたので以下を .zshrc に書いてパスの重複を無くしました。

typeset -U path PATH

emacs の起動ができなかったので brew で再インストールします。

$ brew remove emacs
$ brew install emacs --cocoa --use-git-head
$ brew linkapps

再度 emacs を起動すると以下のようなエラーがでました。migemo を読み込む際に、IME 周りで変なことになっているっぽいです。

Symbol's function definition is void: mac-change-language-to-us

僕は普段 Google 日本語入力を使用しているのですが、Mavericks から U.S. の入力ソースが削除できないっぽい感じになっていました。 少しトリッキーですがこちらを参考にして、一度ことえりを追加したら U.S. を削除できました。

しかし依然として emacs の起動ができません。どうやらインラインパッチのあたった emacs ではないようなので再度インストールします。 /usr/local/Library/Formula/emacs.rb を見るとオプションで制御できるようになっているっぽいのでオプション付きでインストールします。

$ brew remove emacs
$ brew install emacs --cocoa --japanese
$ brew linkapps

これで無事起動するようになりました。いい機会なので少し .emacs の設定を変更しました。こんな感じに設定してます。

これで Mavericks とも仲良く暮らしていけそうです。

追記 7/29 しばらく問題なく使えていましたが、とある Rails のプロジェクトが動かなくて、この原因が OS アップデートによるものだと分かったので追記します。

その Rails プロジェクトでは ffi という gem を使っていたのですが、それが bundle install できませんでした。brew で libffi を unlink もしくは link しても効果がなかったです。以下のようにして直すことができました。

まず Xcode Command Line Tools をインストールしてみる。

 $ xcode-select --install

すると「このソフトウェアは、現在ソフトウェア・アップデート・サーバから入手できないため、インストールできません。」というメッセージが出てインストールできなかったのでこちらを参考にして GUI からコマンドラインツールをインストールしました。ちなみに Xcode は 6-beta4 というベータ版です。

そして bundle install で ffi をインストールしようとしたときに出たエラーが以下です。

You have to install development tools first.

ここを参考にして下記コマンドを実行しました。

$ sudo ln -s /usr/bin/gcc /usr/bin/gcc-4.2

以上で bundle install ができ ffi が入って Rails も動作しました。

こちらのサイトにまとめられています。

Emacs に Swift-mode をインストール

Apple が発表した新言語 Swift が話題になってますね。 ほとんどの人は Xcode で試すのでしょうけど、あんな不便なIDEを使いたくない Emacs 病の人がいるかと思います。

すでに swift-mode なるものが package.el からインストールできるようになってるのでさっそくインストールしましょう。 以下を Emacs で実行すればOK。

M-x package-install swift-mode

GitHub - swift-mode