Can I Swift? その3 – 値の設定の手法

in Swift

Objective-Cはconstをつけることによって、Swiftはletによって変わらない変数を表現できることがわかりました。 しかし変わらない変数は変えることができないが故に1回で値を設定しなければならないという大きな制約があります。 その制約が具体的にどのようなものかコードで見てみましょう。

条件つき値の設定 in Objective-C

通常のローカル変数を使った以下のようなコードがあったとします。

        NSString * title;

        title = getTitle();
        if (title == nil) {
            title = @"Default Title";
        }

変数titleにまず関数getTitle()で取得した値を設定し、その値がnilだった場合には@"Default Title"に設定し直しています。 このような設定処理は実際のプログラムによく現れますが、もし変数titleの値がその後変更されるものでなければ、変わらない変数として宣言して処理を行いたいところです。 書き直してみましょう。

    NSString * const tempTitle = getTitle();
    NSString * const title = (tempTitle != nil ? tempTitle : @"Default Title");

一時変数を別に用意し、三項演算子(?)を用いることによってなんとか変数titleに1回で値を設定することができました。

実はこのような設定処理は気のきいたプログラミング言語においては例えば以下のように簡潔に記述することが可能です。

    String title = (getTitle() || "Default Title")

これが可能になるのはOR演算子(||)が論理値(真OR偽)を返すのではなく、真となった値(この場合は"Default Title")を返すタイプのプログラミング言語の場合です。 残念ながらCを親に持つObjective-Cではこの記述はできません。

条件つき値の設定 in Swift

新言語Swiftでは気のきいた記述が可能になっているかどうか早速テストしてみましょう。

    let title:String = (getTitle() || "Default Title")

Swift Compiler Error: Type 'String' does not conform to protocol 'LogicValue' 残念ながらSwiftでもOR演算子は論理値を返し、Objective-Cから変わりないようです。

クロージャを用いた値の設定

Swiftでの値の設定についてドキュメントThe Swift Programming LanguageInitializationの章にこのような例が載っています。

    let someProperty: SomeType = {
        // create a default value for someProperty inside this closure
        // someValue must be of the same type as SomeType
        return someValue
    }()

値を生成するための複雑な処理をクロージャで記述し、即実行することで値を取得し設定しています。 クロージャはこのような使い方もできて便利ですね。 これが書ければSwiftで値を設定するのに困ることはなさそうです。

しかしちょっと思い出してください。 Objective-Cにもクロージャに相当するBlocksという仕組みがMac OS X 10.6以降、iOS 4以降使えるようになりました。 Blocksを用いてObjective-C版を書き直してみましょう。

    NSString * const title = ^ NSString * {
        NSString * const tempTitle = getTitle();
        if (tempTitle != nil) {
            return tempTitle;
        }
        return @"Default Title";
    }();

見事に値を設定することができました。 この程度の複雑さですと大した恩恵はありませんが、処理が複雑になればなるほどBlocksを利用した値の設定の手法は有用になっていくでしょう。

変わらない変数についての話はこれぐらいとして、次回はまた別のテーマでSwiftを見ていきたいと思います。 ではでは。

Leave a Reply

*


Emacs入門 #1 インストール

in Emacs

少し踏み込んでコンピューターを使うようになってくると、標準のテキストエディターとは別にお気に入りのテキストエディターというのができてくると思います。 私の場合はGNU Emacsで、振り返ってみると人生の3/5ぐらいの間このテキストエディターを使い続けています。

それほどお世話になっているエディターですが改めて紹介したことがなかったので、このブログでも気が向いたときにEmacsについて書いていこうかなと思います。

Mac OS Xにインストールする方法はいくつかありますが、私はMacPortsを利用するのがここ数年の常です。 その場合はこのようにしてインストールします。

sudo port install emacs-app
起動してみましょう。
open /Applications/MacPorts/Emacs.app
Screen Shot 2014-11-23 at 10.14.19

無事インストールすることができたようですね。

実はMac OS Xには標準でコマンドライン版のEmacsがインストールされています。

/usr/bin/emacs
Screen Shot 2014-11-16 at 02.28.44

でもどうせならグラフィカルユーザインタフェース版をインストールして使う方がいいでしょうね。

次回はできれば最低限の設定などについて書いてみたいと思います。 ではでは。

Leave a Reply


Can I Swift? その2 – 変わる変数、変わらない変数

in Swift

プログラムで値を一時的に保持するためにローカル変数というものが用いられますが、私はこの変数の用途は大きく2つあると思っています。 変わる変数としての用途と変わらない変数としての用途です。 変わる方はいいとして変数なのに変わらないなんて矛盾した呼び方ですね。 具体的なコードで見ていきたいと思います。

変わらない変数 in Objective-C

次のコードは実際にLadioCastにあるクラスメソッドで、エラーメッセージをダイアログボックスとして表示する部分です。

+ (NSInteger)alertUserInfo:(NSDictionary *)userInfo {
	// close current alert panel
	[NSApp abortModal];
	if (userInfo == nil) {
		return 0;
	}
	// show new alert panel
	NSString * const messageText = [userInfo objectForKey:NSLocalizedDescriptionKey];
	NSString * const informativeText = [userInfo objectForKey:NSLocalizedRecoverySuggestionErrorKey];
	NSAlert * const alert = [[[NSAlert alloc] init] autorelease];
	alert.messageText = messageText;
	alert.informativeText = informativeText;
	alert.alertStyle = NSCriticalAlertStyle;
	NSInteger const response = [alert runModal];
	
	return response;
}

コードの8,9,10,14行目でローカル変数を定義していますが、全部にconstという修飾子がついています。 constというのは設定された初期値から値を変更できないようにする修飾子で、いわゆる定数を宣言するためのものです。 一般にプログラムで定数というとプログラムを書いた時点で既に値が定まっているようなものが典型的です。 それとは対照的にconstがついたローカル変数は、その処理が実行される間だけ存在しかつその間だけ値が変わらないものになります。 つまりここで使われているローカル変数は全て最初から最後まで値を変えずに役目を終えるわけです。

実際のプログラムにおいてローカル変数に保持された値が最初から最後まで変更されない場合は意外なほど多く、これらは変数といえどもある値に扱いやすい名前、いわば別名を割り当てているだけ、といえます。 変わらない変数という考え方は、このような別名を割り当てているだけの変数を通常の変数と意識して区別しよう、という考え方です。 変わらないものとして区別することでプログラムがより理解しやすくなり、プログラマの精神的な負担が軽減されます。 この区別をObjective-Cの場合はconst修飾子の付加で行うことができましたが、さてSwiftの場合ではどうでしょうか。

変わらない変数 in Swift

うれしいことにSwiftではこの区別をよりはっきりつけることができます。 前出のコードをSwiftで書き直してみましょう。

class func alertUserInfo(userInfo:NSDictionary!) -> Int {
	// close current alert panel
	NSApp.abortModal()
	if !userInfo {
		return 0
	}
	// show new alert panel
	let messageText:String = userInfo.objectForKey(NSLocalizedDescriptionKey) as String
	let informativeText:String = userInfo.objectForKey(NSLocalizedRecoverySuggestionErrorKey) as String
	let alert:NSAlert = NSAlert()
	alert.messageText = messageText
	alert.informativeText = informativeText
	alert.alertStyle = .CriticalAlertStyle
	let response:Int = alert.runModal()

	return response
}

Swiftでは変わらない変数をletで定義することができます。 (それに対して変わる変数はvarで定義します。)

私はあるプログラミング言語が使える言語かどうか仕様を見る際、このように変わる変数と変わらない変数を区別して書けるかどうかを重要項目の1つとしてチェックします。 その意味でSwiftはこのチェックに難なく合格してくれました。

次回はもう少しこのテーマを掘り下げてみたいと思います。 ではでは。

Leave a Reply


らじおぱバージョン2.0.3リリース

in Ladiopa

iOSアプリらじおぱを更新しバージョン2.0.3としてリリースしました。 このリリースでの変更点は以下のとおりです。

  • アーカイビング中の動作を改善しました。

具体的にはらじおぱがフォアグラウンドで動作していてかつアーカイビングを実行している間はスクリーンロックに移行しない処理を追加しました。

別途iOS 7の機能についてその後開発者チケットを使ってApple担当者と直接やりとりしたりしてらじおぱに必要な修正を要望し続けていますが、今後の展開は未だに不透明な状況です。

ではでは。

Leave a Reply


Can I Swift? その1 – 前置き

in Swift

現地時間の6月2日に行われたWWDC(The Apple Worldwide Developers Conference)でのAppleの発表で一番の注目点は新プログラミング言語Swiftでした。

Swiftの特徴を簡単にいうと現代的なプログラミング言語の機能をふんだんに取り入れつつ、既存のCocoaフレームワーク(Mac OS X)およびCocoa Touchフレームワーク(iOS)をそのまま利用できるよう意図された言語ということができます。 これまでCocoa, Cocoa Touchフレームワークを利用できる言語はObjective-Cだけだったわけですが、それと並ぶ開発言語になります。 またObjective-Cに対するSwiftの位置付けはAndroidの開発言語Javaとの対比でいうとJavaに対するScalaの位置付けに近い感じがします。 (余談ですがScalaについてはLadiopa for Androidを開発する際に開発言語として使えないか調べ、不可能ではないもののGoogle非公式ゆえのハンディが大き過ぎて断念した経緯があります。)

さて実際のソフトウェア開発にSwiftは本当に使えるのでしょうか。 ちょうどよい機会ですので、私がObjective-Cでプログラムを書く際に常々有用だと考えている書き方を紹介しつつ、それがSwiftでも実現できるかどうかという視点でそれを探っていきたいと思います。

毎回1テーマでおそらく3、4回ぐらいの続き物になるかなと思っています。 ではでは。

Leave a Reply