MOSA Multi-OS Software Artists

MOSAはソフトウェア開発者を支援します

  • iPhone/iPod touch アプリ紹介
  • MOSA掲示板
  • 活動履歴
  • About MOSA(English)

MOSA Developer News[MOSADeN=モサ伝]第294号

2008-04-08

目次

  • 「「Wonderful Server Life」    第68回   田畑 英和
  • 小池邦人のCarbon視点でCocoa探求
  • ターミナルの向こうから      第23回  海上 忍 

「Wonderful Server Life」  第68回  田畑 英和

  〜Open Directory編〜

 今回はサーバ構成が「ワークグループ」の場合のアカウント管理について解説します。基本的には「標準」構成の場合と同様ですが、さらに機能が追加されています。

 アカウント管理の解説を始める前に「ワークグループ」について改めて解説しておきます。「ワークグループ」としてサーバを設定する方法は2通りあります。まず1つ目はLeopard Serverのインストール後にサーバ構成を「ワークグループ」としてセットアップする方法です。この場合セットアップ中にほかのディレクトリサーバへの接続を設定します。
 もう1つは最初は「標準」としてセットアップし、あとからほかのディレクトリサーバに接続する方法です。つまり「標準」と「ワークグループ」の違いは、ほかのディレクトリサーバに接続しているかどうかの違いということになります。ディレクトリサーバへの接続は「ディレクトリユーティリティ」を使用します。
 サーバ構成がどちらになっているかは「サーバ環境設定」の「情報」を表示して「サーバのタイプ」をみれば確認できます。

・サーバのタイプ
http://www.htabata.com/Site/LeopardServer/Pages/Server_Preferences%28Standard%29.html#32

◇ワークグループのユーザ管理
 では「ワークグループ」でのアカウント管理についてみていきましょう。まずはユーザからです。「ワークグループ」構成のサーバで「システム環境設定」の「ユーザ」を表示しますと画面がほんの少しだけ「標準」構成とは異なります。ユーザを追加する「+」ボタンが画面左下にありますが、ここにメニューが追加され、「ディレクトリからユーザを読み込む」が選択可能になります。

・ワークグループ構成のユーザ管理
http://www.htabata.com/Site/LeopardServer/Pages/Server_Preferences%28Workgroup%29.html#1

 この追加されたメニューを実行しますと、接続先のディレクトリサーバからユーザを読み込むことができます。読み込みはユーザ単位のほかにグループを指定して読み込むこともできます。グループから読み込むにはギアアイコンのメニューから「グループからユーザを読み込む」を選択します。

・グループからの読み込み
http://www.htabata.com/Site/LeopardServer/Pages/Server_Preferences%28Workgroup%29.html#3

 この読み込み機能ですが、読み込んだからといってオリジナルの(つまり接続先のディレクトリサーバ上の)ユーザアカウントを削除してはいけません。なぜならば、ユーザアカウントの本体はあくまでも接続先のディレクトリサーバ上にあるからです。これは、ユーザアカウントのエイリアスをワークグループサーバ上に作成したと考えると分かりやすいでしょう。ただしたんなるエイリアスではなく、ワークグループサーバ上では読み込んだユーザアカウントに属性を追加することができるのです。このようにして、オリジナルのアカウントにはなにも修正を加えずに、ユーザ属性を管理することができるようになるのです。

 このようなユーザの読み込みはLeopard Serverの新規で、読み込んだユーザのことをAugmented Usersと呼んでいます。ディレクトリサーバ上のアカウントに直接属性を追加する場合、スキーマの拡張が必要であったり、そもそも属性の追加ができなかったりする場合がありますが、Augmented Usersを利用することにより、より柔軟なユーザ管理が可能になります。
 特にLeopard Serverになってからユーザ属性に様々な情報を追加するようになってきましたので、ユーザ属性を自由に管理できることは重要になります。

◇ワークグループのグループ管理
 「ワークグループ」ではグループ管理にも機能が追加されます。「システム環境設定」の「グループ」を表示すると「外部メンバー」ボタンが追加されていることが分かります。この外部メンバーでは接続先のディレクトリサーバ上に存在するアカウント(ユーザもしくはメンバー)をワークグループサーバ上のグループのメンバーとして追加することができます。
 異なるディレクトリ上のアカウントをグループのメンバーにすることは、すでにTiger Serverから可能でしたが、「システム環境設定」から容易に外部メンバーを追加できるようになりました。この機能を利用することで異なるディレクトリ上のアカウントを1つのグループとして管理できるようになります。

・外部メンバー
http://www.htabata.com/Site/LeopardServer/Pages/Server_Preferences%28Workgroup%29.html#8

 以上が「ワークグループ」構成で利用可能なアカウント管理機能になります。ほかのディレクトリサーバとの連携が「サーバ環境設定」のシンプルなGUIで実現できるといったところがポイントになります。それでは次回は「ディレクトリユーティリティ」を使用した、ディレクトリサーバへの接続について解説する予定です。
次回へつづく                             

小池邦人のCarbon視点でCocoa探求(2008/04/04)

〜 プロパティとプロトコル 〜

今回からは、画像ファイルを読み込んで、そのパス名などをImageFileオブジェクトへと登録する仕組みをどうするのか順次考えて行きます。その前に、せっかくObjective-C 2.0を使うわけですから、以前に作成したImageFileクラスのインスタンス変数を「プロパティ」仕様に準拠させてみます。

インスタンス変数をプロパティ仕様に準拠させれば、自動的にコンパイル側でそれへのアクセッサメソッドを作成してくれます。ですから、アクセッサメソッドを別途ソースコードとして記述する必要はなくなります。また、C言語での構造体メンバーへのアクセスと同じように、「ドット演算子」を用いて、インスタンス変数へのアクセスが可能となります。例えば、こんな感じのソースコードが記述可能になるわけです。

ImageFile    *image;

if( image=[[ImageFile alloc]init] )
{
  image.name=@"Untitled";
  image.type=@"JPEG File";
  image.kind=1;
  image.flag=0;
}


ドット演算子経由での変数アクセスを考慮し(今のままでは見づらいので)、今回からインスタンス変数の先頭のアンダーラインは外すことにしました。この「先頭アンダーライン」ですが、荻原剛志さんの著書「Objective-C」には、先頭にアンダーラインを付けたインスタンス変数は避けるべきだと記載されています。Apple社が、Framework内のクラスなどで使用することはOKだが、一般開発者は使用しない方が良いと言う説もあります。ところが、Apple社のサンプルソースコードを見ると、何のためらいもなく使用している場合もあり(笑)Cocoa開発者を悩ませます。さて、何が正解なのでしょうか?

ともあれ、ImageFileクラスで用意したインスタンス変数をプロパティ仕様に準拠させるには、クラスの雛形宣言(ImageFile.h)の中で@property宣言を使いインスタンス変数を列挙します。

@interface ImageFile : NSObject 
{
   NSString        *path;
   NSString        *type;
   CGRect          srt;
   unsigned int    flag;
   int             kind;
   int             para;
}

@property(retain)NSString      *path;
@property(retain)NSString      *type;
@property(assign)CGRect         srt;
@property(assign)unsigned int   flag;
@property(assign)int            kind;
@property(assign)int            para;

@end


@propertyに続くカッコ内の(retain)は、プロパティの「属性」と呼ばれており、retain、assign、copy、readonly、readwriteなど幾つかの種類があります。それらの詳しい機能については、以下のドキュメント(日本語訳)を参照してみてください。

「Objective-C 2.0プログラミング言語 」
http://developer.apple.com/jp/documentation/Cocoa/Conceptual/ObjectiveC/

例えば、属性がそれぞれretain、assign、copyであると、コンパイラが作成するアクセッサメソッドのタイプが次のように変わります。

// assignの場合

- (void)setKind:(int)newKind
{
   kind=newKind;
}

// retainの場合

- (void)setPath:(int)newPath
{
   if( path!=newPath )
   {
       [path release];
       path=[newPath retain];
   }
}

// copyの場合

- (void)setPath:(int)newPath
{
   if( path!=newPath )
   {
       [path release];
       path=[newPath copy];
   }
}


オブジェクトでないインスタンス変数(intやfloatや構造体など)であれば、assign属性でOKだと言うのが理解できます。今回は、NSStringの場合にだけretain属性を使います。そして、もう一カ所だけプロパティに関係する定義を記述しておくべき箇所があります。それはクラスの実装部分(ImageFile.m)の方です。対象となるインスタンス変数について@synthesize宣言しておきます。実際の定義は、以下のようになります。

@implementation ImageFile

@synthesize path,type,srt,flag,kind,para;

// 各種メソッド表記

@end


プロパティ宣言についてはこれで完了です。ところで、ImageFile.hの@interface行の最後を見てみると、そこにという記述がありますが、これは、ImageFileクラスがNSCodingプロトコルに準拠していることを意味しています。プロトコルとは、幾つかのメソッド(ひとつでも良い)のグループを指しており、そのメソッドをすべて実装したクラスのみが「そのプロトコルに準拠している」と呼ばれます。NSCodingプロトコルはNSObject.hに定義されており、以下の2つのメソッドを持つクラスがそれに準拠していることになります。当然、あるだけではなく、それらのメソッドがプロトコル定義の意図した動作をしないといけません。

@protocol NSCoding

- (void)encodeWithCoder:(NSCoder *)aCoder;
- (id)initWithCoder:(NSCoder *)aDecoder;

@end


つまり、ImageFileクラスに、上記2つのメソッドを実装する必要があるわけです。これらのメソッドはどういう働き(機能)をするのでしょうか? 前回、NSDocumentメソッドをオーバライドして、以下の2つのメソッドを実装しました。dataOfType:error:メソッドは、ファイルにドキュメントを書き出すために、オブジェクトをバイナリデータ(NSData)に変換します。また、readFromData:ofType:error:メソッドは、ファイルから読み込んだバイナリーデータ(NSData)からオブジェクト(NSMutableArray)を再構築します。

- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError

- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName
                                       error:(NSError **)outError


両メソッドの実際の処理に注目してみましょう。NSMutableArrayをバイナリー
データ(NSData)に変換しているのは、NSArchiverクラスのarchivedDataWithRootObject:メソッドです。逆にバイナリーデータ(NSData)をNSMutableArrayに戻しているのは、NSUnarchiverクラスのunarchiveObjectWithData:メソッドです(こちらでもインスタンス変数の_listは先頭のアンダーラインを取りました)。この2つのアーカイブとアンアーカイブメソッドは、対象となるオブジェクトのクラスがNSCodingプロトコルに準拠していることが前提で使用されています。

data=[NSArchiver archivedDataWithRootObject:list] ) // バイナリーデータ作成

if( array=[NSUnarchiver unarchiveObjectWithData:data] ) // データからNSArrayを得る
    [list addObjectsFromArray:array]; // インスタンス変数に保存する

NSArray.hを見ると、NSMutableArray(NSArrayのサブクラス)は、NSCodingプロトコルに準拠していることが分かります。

@interface NSArray : NSObject                                                            NSFastEnumeration>

よって、NSMutableArrayに対しては両メソッドを使用しても大丈夫ですが、その配列に代入されているImageFileオブジェクトの方は、NSCodingプロトコルに準拠しないと問題が生じます。つまり、ImageFileクラスにencodeWithCoder:とinitWithCoder:メソッドを実装する必要があり、具体的には、ImageFileオブジェクトからNSDataへ変換するアーカイブ処理と、NSDataからImageFileオブジェクトへ戻すアンアーカイブ処理の両方を実現しておくことになります。

本アプリケーションでドキュメントのロードやセーブを実現するには、ImageFileクラスに対してもう一仕事する必要があることが分かりました。次回では、先んじてこの点を解決してから画像ファイル関連の話へ移りたいと思います。
つづく
                                

ターミナルの向こうから      第23回  海上 忍

〜  日本語文字コードについて考える (2)〜

 ありがたいことに、世の中にはさまざまな文字コード変換ツールがフリーで配布されています。前回は文字コード変換用のコマンドを紹介しましたが、今回はPerlモジュールの形で実装された文字コード変換用の関数 / コンポーネントの使い方を紹介します。

・Perlで日本語文字コード変換
 Mac OS X 10.5(Leopard)には、Perl 5.8.8が標準装備されています。シェル(ターミナル)またはAutomatorから呼び出すスクリプトの形で利用できるため、広範囲に活用できます。
 Perlには、日本語環境用に文字コードの変換を行う拡張モジュールが数種類存在します。ここでは、CGIでの利用も考慮して、Perl 5.8以前の環境でも利用できる「Jcode.pm」と、Perl 5.8以降に標準装備されている「Encode.pm」の2つのモジュールの使い方を紹介します。

i) Jcode.pm
 日本語文字コード変換を行うためのPerlモジュールです。バージョン5.8のPerl以降では、Jcode.pmが持つすべての機能は、新たに標準のモジュールとして採用された「Encode.pm」に引き継がれているため、積極的に選択する必要はありませんが、なんらかの理由で旧バージョンのPerlを使用する場合には有用です。なお、Jcode.pmのインストール方法は、第21回をご参照ください。
 Jcode.pmの機能は、Perlスクリプトの先頭部分に「use Jcode;」の1行を挿入し、「Jcode::convert($str, $out-code, $in-code, “z”);」の要領で使用します。もっとも、ソースとなる文字列から新しくオブジェクトを生成する、すなわち「$result = Jcode->new($source, “utf8″)->sjis;」の要領で記述するほうがスマートでしょう。

- - - - -
リスト1:Jcode.pmで文字コードを変換(EUC→S-JIS)する

use Jcode;
$result = Jcode->new($source, "euc")->sjis;
- - - - -


 入力する文字列の符号化形式を、自動判定させる方法もあります。その場合には、入力の符号化形式を省略するだけでOKです。たとえば以下の例では、対応する文字コード種(ISO-2022-JP=”jis”、シフトJIS=”sjis”、日本語EUC=”euc”、UCS-2=”ucs2″、UTF-8=”utf8″)で符号化された日本語文字列を、シフトJISとして変数(result)に代入しています。

- - - - -
リスト2:符号化形式を自動判定してシフトJISに変換する

$result = Jcode->new($source)->sjis;
- - - - -

 余談ですが、工夫すれば文字コード変換用のコマンドとしても活用できます。入力する文字列(ファイル)の符号化形式は、前述のとおり省略すると自動判定されるので、かなり簡略化することが可能です。たとえば、以下のコマンド実行例では、オリジナルを拡張子「.bak」付きのファイルとしてバックアップしつつ、目的のテキストファイル(source.txt)の符号化形式をUTF-8に変換しています。AutomatorやAppleScriptで文字コード変換だけを目的に使うのであれば、この応用で十分対応可能でしょう。

- - - - -
コマンド実行例:

$ perl -MJcode -i.bak -lpe 'jcode( $_)->utf8' source.txt
- - - - -


ii) Encode.pm
 Leopardに付属のPerlには、Jcode.pmの後継モジュール「Encode.pm」が標準装備されています。改良点としては、Jcode.pmでEUC-JPからUTF-8に変換すると、チルダ「~」が文字化けしてしまう(unicode::japanese、http://search.cpan.org/dist/Unicode-Japanese/ を使用するなど回避法あり)など、Unicodeの扱いに生じていた問題が解消されたことが挙げられます。
Encode.pmの場合、標準の状態でUnicodeに対応しています。処理速度も、Jcode.pmをかなり上回ります。
 Encode.pmの機能は、Perlスクリプトの先頭部分に「use Encode;」の1行を挿入すれば利用できます。日本語EUCからシフトJISに変換することを例にすると、オーソドックスな書き方では「from_to($str, ‘euc-jp’,'shiftjis’);」、オブジェクト指向的に書けば「$data = encode(‘shiftjis’,decode(‘euc-jp’, $str));」といったところです。

- - - - -
リスト3:Encode.pmで文字コードを変換(EUC→S-JIS)する

use Encode;
$data = encode('shiftjis', decode('euc-jp', $str));
- - - - -


 ただし、符号化形式の自動判定機能を利用するには、Encode::Guessモジュールが必要です。その際、事前に候補となる文字コードを列挙しておかなければならず、デコードに成功したものが複数だった場合、成功した方式の文字列を返すという仕様があるため、ごく短い文字列の変換が思いどおりに行かないことがあります(試しに、以下のサンプルで$dataを「あいうえお」としてください)。簡便さを優先するならば、速度を犠牲にしてもJcode.pmを使うほうがいいでしょう。

- - - - -
リスト4:Encode::Guessを利用した文字コードの自動判定

use Encode;
use Encode::Guess qw/shift-jis euc-jp 7bit-jis/;
$data = "ここに日本語の文字列を入力します";
$data = encode('shiftjis', decode('Guess', $data));
print $data;
- - - - -

◇MOSAからのお知らせと編集後記は割愛します◇

 

 MOSA Developer News   略称[MOSADeN=モサ伝]
        配信停止 mailto:mosaden-ml@mosa.gr.jp
 記事内容に関するご意見 mailto:mosaden-toukou@mosa.gr.jp
      記事投稿受付 http://www.mosa.gr.jp/?page_id=850
Apple、Mac OSは米国アップル社の登録商標です。またそのほかの各製品名等
はそれぞれ各社の商標ならびに登録商標です。
このメールの再配信、および掲載された記事の無断転載を禁じます。
特定非営利活動法人MOSA  http://www.mosa.gr.jp/
Copyright (C)2007 MOSA. All rights reserved.