日本でハリウッドVFXを制作! 「経産省アイディアボックス」 結果:  
●まとめエントリはこちら ●FAQ ●お問い合わせは左のメールフォームから

2009年12月28日月曜日

命令構文と関数構文(2): 「命令構文」

さて「構文」の意味がわかったので、「命令構文と関数構文の違い」についてさらに調べていきたい。
「構文」の定義から推測すると、どちらも「具体的な記号や文字の使用方法と、配置」について説明しているはずである。

まずは「命令構文」について見ていきたい。


----------------------------------------
(1)「命令」の種類

オンラインヘルプ「命令構文」の説明として「命令コマンドの構文・・・・」と書かれている。
これは英語表記では「The imperative command syntax」となっている。

「命令」と「コマンド」という日本語ではどちらも「命令」と訳すことが出来るがここではあえて区別され使われているのでその理由を考えてみた。

調べるとコンピュータ用語で「命令」と訳すことができるのは「imperative」以外に
Instruction
command
のふたつがある。

まず、この二つの意味的な違いを明確にしておきたい。


●「命令(Instruction)」

Wikipedia
命令(めいれい)とはCPUが処理する操作のこと。
英語版Wikiをみると「単一の操作」となっている)
通常、命令操作部と複数のオペランドからなる。
あるいは操作者がコンピュータに入力する簡易な書式による指示の総称として用いられることもある。
通常、加算・減算・乗算・除算の四則演算、ロード・ストア命令、条件分岐命令などからなる。


IT用語辞典BINARY
この命令によって、CPUの動作を直接操作し演算処理やデータの入出力を行わせることが可能となる。



●「コマンド (command)」
Wikipedia
特定のタスクをコンピュータに実行させるための指示の一種であり、プログラムが一種のインタプリタとして解釈し実行する。
シェルなどのコマンド行インタフェースへの指示をコマンドと呼ぶことが多い。
(例:Unix系シェルなどで、ディレクトリを変更するための cd /home/peteといったコマンド)

IT用語辞典
コマンドとは、ユーザがキーボードなどで特定の文字列を入力してコンピュータに与える「命令」のこと。
DOSプロンプトやUNIXコンソールでの作業は基本的にコマンドを用いて行われる。
Windowsの「ファイル名を指定して実行」も、ファイル名をキーボード入力して起動するという意味で、コマンドの入力に近い特徴をもつ。


IT用語辞典BINARY
ソフトウェアの機能を指定し、実行させること。キャラクターベースのOS(CUI)やプログラミング言語で用いられる。


●違い
以上から考えると通常は以下のような意味らしい。
Instruction:CPUを直接的に操作するような命令のこと。
Command:インタプリタ的で、プログラム(ソフトウエア)が解釈し、機能を指定し実行するために使われる。

Melはインタプリタの性質を持っており、ソフトの機能を指定し実行しているので、「Command」ということになるだろう。
(実際ヘルプにはMelコマンドとなっているし)



オンラインヘルプで「命令構文」の説明では「命令コマンドの構文」とあるが、
「命令(Imperative)」は「構文(Syntax)」にかかっているのか、「コマンド(command)」にかかっているのかは、現時点の自分の知識では明確に出来なかった。
ここでのねらいは「関数構文」との違いを明確にすることなので、そのあたりは将来の課題としておき、先へ進みたい。


----------------------------------------
(2)命令構文

オンラインヘルプの「命令構文」をもう一度、読み直してみる。
命令コマンドの構文は、UNIX や DOS シェルのコマンドに似ており、コマンド名の後に任意のフラグや引数を使用します。
sphere -name "martha" -radius 10;
命令形は完結した文で、末尾には必ずセミコロンを付けます。


この部分の記述は以前ははっきりとわからなかったが、「Command」の意味を調べたことから、Melのコマンドがシェルのコマンドと類似していることがすんなりと理解できるようになった。
これは「Command」の意味を調べなければ、UNIXやDOSのことが述べてある理由はわからないままだった。

こういう予備知識がないとすんなりとは理解しずらいことが、平気で、しかも突然でてくるので、コンピュータ系の勉強は混乱させられることが多い。
しかも「知ってて当然」みたいなので、初心者向けの説明のはずなのに「知らないの?」とイヤミをいわれているような気持ちにさえなる。
知らないのに一生懸命勉強している側からすれば、イヤミか、もしくはいじめか、それとも教える側が高飛車なのか、知識をひけらかそうとしているのか?と邪推してしまう。
これがコンピュータの学習の嫌なところだ。w


さて、オンラインヘルプの続きを見ると、以下のように書いてある。
エクスプレッションの一部としてコマンドの命令構文を使用する場合には、コマンドをバッククォーテーションで囲む必要があります。


●エクスプレション

ここで「エクスプレッション」とはどういうものか、もう一度、おさらいしてみたい。
以前のエントリ「構文 (1)」でもふれたことがあるが、オンラインヘルプ「エクスプレッション、演算子および文」には以下のように書かれている。
エクスプレッションとは、新しい値を導く一連の値と演算子です。
MEL のコマンド構文でエクスプレッションを使用する場合、エクスプレッションをカッコで囲む必要があります。

「演算子」とは「+」「-」「*」「/」といった算術演算子、「==」 「<」といった比較演算子、「!」「&&」といった論理演算子のことである。また変数の代入に使う「=」は代入演算子である。 「新しい値を導く一連の値と演算子」の具体例としては、「5 == 10」というような表記がそうだ。

2行目で述べているのは、エクスプレッションをMelコマンド構文内で使うことについて述べている。
「コマンド構文」には「命令構文」も「関数構文」も含まれることは前回調べたとおり。
それらの文の中でエクスプレッションを使うときはエクスプレッションを「( )」で囲むことが必要と言っている。

これについては例をあげて検証していきたい。

(例1)
if文の条件部分を書くとき、
if($a=1);

などと記載するが
if $a=1;

とは書かない。

これは「$a=1」がエクスプレッションだから「コマンド構文の中で使用するときには( )で囲む」という決まりに沿っているからだと思われる。


(例2)
printコマンドでエクスプレッションを使った例
print (Cone.scaleY + "\n");

(例3)
setAttrコマンドでエクスプレッションを使った例
setAttr ($object + ".tx") 2;


●エクスプレッションの一部として命令構文を使用する

話がエクスプレッションの説明にそれたので、再びオンラインヘルプ「命令構文」の説明文に戻ることにする。
エクスプレッションの一部として命令構文を使用する場合には、コマンドをバッククォーテーションで囲む必要があります。」と続いている。


(例1)代入演算子「=」を使った例
まず以下を実行するとエラーになる。
{
string $a[] = sphere -r 10;
print $a[0];
}
// Error: string $a[] = sphere -r 10; //
// Error: Invalid use of Maya object "r". //

代入演算子「=」を用いる場合それは、エクスプレッションである。
エクスプレッションの定義は「新しい値を導く一連の値と演算子」であり、代入演算子は右辺の値を左辺へ代入するエクスプレションである。

しかし、この例では、左辺は「変数」であり、右辺は「命令構文」となっている。
「変数」は「一連の値」の一つとみなすことができるが「命令構文」は「値」ではない
よってこれがエラーとなるのは理解できる。

「命令構文」のルール「エクスプレッションの一部として命令構文を使用する場合には、コマンドをバッククォーテーションで囲む」に従い、「sphere」コマンド部分をバッククォーテーションで囲めば、エクスプレッションの一部として正常に動作し、$a[0]に「nurbsSphere1」の名前が収まる。

{
string $a[] = `sphere -r 10`;
print $a[0];
}

nurbsSphere1 (スクリプトエディター内の出力)

これは「sphere」コマンド(命令構文)を実行した結果の戻り値と一致している。
sphere;
// Result: nurbsSphere1 makeNurbSphere1 //

ちなみにこの戻り値には「makeNurbSphere1」があるが上記のスクリプトの$a[0]を$a[1]に変更すればその戻り値がきちんと格納されていることが確認できる。


ここでふと疑問に思うのが「sphere」コマンド自体に戻り値はある。
ちゃんとスクリプトエディターには出力されている。
それなのになぜ機能しなかったのか?

実は、このことはオンライヘルプ「コマンド構文」の最後に明記してある。
戻り値を使用する: 関数構文とバッククォーテーション
命令構文を使用すると、コマンドはスクリプト エディタ(Script Editor)に戻り値を出力するだけで、使用できる戻り値は提供されません。


(例2)比較演算子を使用するエクスプレッションの例
まず、
sphere -r 5;
で半径5のNurbsスフィアを作成。

そのスフィアが選択された状態で、以下のスクリプトを実行。

if(`sphere -query -r` == 5)
print "radius is 5";
}

これで「radius is 5」と表示される。

if文はコマンド構文であり、比較演算子を使う部分は左辺、右辺を含めてエクスプレッションである
コマンド構文内でエクスプレッションを使用するので、エクスプレッションをカッコ「( )」で囲む必要がある。
(***** == 5)

またエクスプレッションの一部として命令構文「sphere -query -r」を使っている
よって、それをバッククォーテーションで囲む必要がある。
`sphere -query -r`

上記二つのルールが組み合わさったことにより、
(`sphere -query -r` == 5)
という表記ができあがっている。



上記のことから「`(命令構文)`」=「戻り値」=「値」であることがわかる。


これと似たような機能をするのが「eval」である。

evalの場合は、「( )」の中身をstringとして扱うので「" "」で囲む。
{
string $a[] = eval("sphere -r 10");
print $a[0];
}

しかし、evalの場合、ヘルプにあるとおり、「戻り値は、コマンドを実行した結果を表す文字列」である。
 

----------------------------------------
まとめ
----------------------------------------
●「Command」とは特定のタスクをコンピュータに実行させるための指示
 ソフトウエアが一種のインタプリタとして解釈、実行する。
 Melコマンドという名前が示すとおりである。

●命令構文:コマンド名の後に任意のフラグや引数を使用する。
命令形は完結した文で、末尾には必ずセミコロンを付けます。

●「命令構文」は戻り値をスクリプトエディタ上にしか出力できない。

●エクスプレッションとは、新しい値を導く一連の値と演算子。
(例)代入演算子、比較演算子などを用いる場合その左辺と右辺を含めてエクスプレッションである。

●「`(命令構文)`」=「戻り値」=「値」=「変数」と相互に入れ替えることが出来る。

●コマンド構文の中でエクスプレッションを使用する場合、エクスプレッションをカッコで囲む。
(例1)コマンド構文########(エクスプレッション)########
(例2)if($a=1);
(例3)setAttr ($object + ".tx") 2;

●エクスプレッションの一部として命令構文を使用する場合には、コマンドをバッククォーテーションで囲む。
(例1)エクスプレッション*********`コマンド(命令構文)`*********
(例2)string $a[] = `sphere -r 10`;
(例3)if(`sphere -query -r` == 5)

●コマンド構文の中で、エクスプレッションを使用し、かつエクスプレッションの一部として命令構文を使っている場合。
(例1)コマンド構文####(エクスプレッション****`コマンド(命令構文)`****)####
(例2)if(`sphere -query -r` == 5)

<例によって、知識不足から来る間違いがあるかもしれませんので、使用に当たっては自分で確認をしてください。>

「命令構文」の定義については、調べ切れていないと思っているので、わかり次第、追加したいと思っています。
 
  

0 件のコメント:

コメントを投稿