REBOL-Core User Manual Chap5/ja

From DocBase

Jump to: navigation, search

Contents

Chapter 5 - Scripts

REBOL/Core Users Guide
Main Table of Contents
Send Us Feedback 

(Original: http://www.rebol.com/docs/core23/rebolcore-5.html ) (Translation ver. 0.3)

1. Overview

スクリプトという用語は、評価されるファイルが一つのファイルの場合だけを指すのもなければ、他の種類のファイルに埋め込まれたソーステキスト(webページのような)だけを指すのでもなければ、データファイルとしてセーブされるものやメッセージとして送信されるソーステキストの断片だけを指すのでもない。

1.1 File Suffix (ファイルと接尾辞(拡張子))

REBOLスクリプトは、典型的には .r 接尾辞(拡張子)がファイル名に付いている; しかし、この習慣は必須のものではない。 インタプリタは、どのような接尾辞(拡張子)が付いたファイルでも読むし、妥当なREBOLヘッダのために内容をスキャンする。

1.2 Structure (構造)

スクリプトの構造はフリーフォームだ。 インデンテーションやスペース空けは、スクリプトの構造と内容を明らかにするために使われる。 付け加えれば、あなたは、誰にとっても読みやすいスクリプトを作るために、標準的なスクリプティングスタイルを使うことが推奨される。 より詳細な情報については、Style Guide〔訳注:この章の5節〕を参照のこと。

2. Headers

スクリプト本体の直前に、どのスクリプトであっても、その目的やスクリプトについてのそれ以外の属性を明らかにするヘッダがなければならない。 ヘッダには、スクリプト名、作者、日付、バージョン、ファイル名、そして追加情報などが含まれる。 直接評価されることを意図していないREBOLデータファイルには、ヘッダは不要だ。

ヘッダはいくつかの理由で有益だ。

  • スクリプトが、REBOLインタプリタにとって妥当なソーステキストであることを明らかにする。
  • インタプリタは、スクリプトのタイトルを表示したり、そのスクリプトの評価に先立って、どのようなリソースやバージョンが必要かを知ることが出来る。
  • ヘッダは、タイトル、目的、作者、そしてスクリプトについてのその他の詳細について、コミュニケートする標準的な方法を提供する。あなたは、スクリプトのヘッダから、あるスクリプトに興味があるかどうかを知ることが出来る。
  • スクリプトアーカイブとwebサイトは、スクリプトディレクトリ、カテゴリ、相互参照を生成するためにヘッダを用いる。
  • ある種のテキストエディタは、作者や、日時、バージョン、そして履歴などの情報の後を追うためにスクリプトのヘッダにアクセスしたりアップデートする。

ヘッダの一般的な形式は以下の通り:

REBOL [block]

インタプリタがヘッダを認識できるように、ブロックはワードREBOLの直後に書かれなければいけない。 ホワイトスペース(半角スペース、タブ、そして〔空〕行)だけが、ワードREBOLとブロックの間に入っていい。

REBOLワードに続くブロックは、スクリプトに関して記述した〔目的定義(object definition)(?)〕である。 望ましい最小のヘッダは次のようなものだ:

REBOL [
    Title:  "Scan Web Sites"
    Date:   2-Feb-2000
    File:   %webscan.r
    Author: "Jane Doer"
    Version: 1.2.3
]

スクリプトが読み込まれると、ヘッダブロックが評価され、そのワードはそれらの定義の値に設定される。 それらの値は、インタプリタによって使われたり、スクリプト自身によって使われる場合も有る。

ワードの定義は、単一の値だけでなく、ブロックに入れることで複数の値を定義することも可能だ:

REBOL [
    Title: "Scan Web Sites"
    Date:   12-Nov-1997
    Author: ["Ema User" "Wasa Writer"]
]

作者についての情報や、著作権、形式、バージョンによる要求事項、改訂履歴、その他を含むことで、ヘッダはもっと複雑になるかもしれない。 ヘッダオブジェクトを構築するのにブロックを使っているので、新しい情報を追加して拡張することもできる。 つまり、スクリプトは必要に応じてヘッダを拡張できる。しかし、曖昧であるとか、冗長な情報を裂けるように注意しなければならない。

完全なヘッダは、おそらく次のようなものになるだろう:

REBOL [
    Title:   "Full REBOL Header Example"
    Date:    8-Sep-1999
    Name:    'Full-Header  ; For window title bar

    Version: 1.1.1
    File:    %headfull.r
    Home:    http://www.rebol.com/rebex/

    Author:  "Carl Sassenrath"
    Owner:   "REBOL Headquarters"
    Rights:  "Copyright (C) Carl Sassenrath 1999"

    Needs:   [2.0 ODBC]
    Tabs:    4

    Purpose: {
        The purpose or general reason for the program
        should go here.
    }

    Note: {
        An important comment or notes about the program
        can go here.
    }

    History: [
        0.1.0 [5-Sep-1999 "Created this example" "Carl"]
        0.1.1 [8-Sep-1999 {Moved the header up, changed
            comment on extending the header, added
            advanced user comment.} "Carl"]
    ]

    Language: 'English
]

2 Prefaced Scripts (序文つきスクリプト)

スクリプトテキストはヘッダから始まっている必要はない。 スクリプトはどのようなテキストであれ、例えばemailのメッセージやwebページ、その他のファイルに挿入できるようなものであれば、どのようなテキストで始まっていても構わない。

ヘッダはスクリプトの開始位置を示し、それに続くテキストはスクリプトの本体になる。 ヘッダの前に現れるテキストは、序文と呼ばれ、評価の最中は無視される。

The text that appears before the header is ignored
by REBOL and can be used for comments, email headers,
HTML tags, etc.

REBOL [
  Title:   "Preface Example"
  Date:    8-Jul-1999
]

print "This file has a preface before the header"

2 Embedded Scripts (埋め込みスクリプト)

スクリプトの後に、スクリプト自身とは関係のない他のテキストが続く場合、スクリプト全体がスクエアブラケット [ ] で囲まれていなければならない:

Here is some text before the script.

[
    REBOL [
        Title:   "Embedded Example"
        Date:    8-Nov-1997
    ]
    print "done"
]
Here is some text after the script.

最初のブラケットとワードREBOLの間にはホワイトスペースのみが許される。

3. Script Arguments (スクリプトの引数)

スクリプトが評価される時、自分自身の情報にアクセスする。これはsystem/scriptオブジェクトで見つかる。 このオブジェクトはsystem/scriptのためにObject Field内でリストされているフィールドを含んでいる。

Header スクリプトのヘッダオブジェクト。これは、スクリプトのタイトルや作者、バージョン、日付、その他のフィールドにアクセスするのに使われる。
Parent スクリプトが他のスクリプトから評価されている場合、その親スクリプトのためのsystem/scriptオブジェクト。
Path 評価されているスクリプトのファイルディレクトリのパス、あるいはURL。
Args スクリプトの引数。これらは、オペレーションシステムのコマンドラインや、あるいはスクリプトを評価するのに使ったdo関数から渡される。

スクリプトオブジェクトの使用例を挙げよう:

print system/script/title

print system/script/header/date

do system/script/args

do system/script/path/script.r

最後の例は、現在実行中のスクリプトと同じディレクトリに有るscript.rという名前のスクリプトを評価する。

3.1 Program Options (プログラムオプション)

スクリプトは、REBOLインタプリタが起動した時に渡されるオプションを指定することも可能だ。これらは、system/optionsオブジェクトで定義されている。オブジェクトは、Object Fieldsのセクションに挙げたフィールドをsystem/optionsのために持っている。

Home あなたのオペレーティングシステムの環境によって決まるファイルパス。環境変数HOMEや、あるいはシステムレジストリに設定されているパスだ。これは、rebol.rとuser.rファイルを見つけるのに使われるパスだ。
Script インタプリタが起動された時のイニシャルスクリプトとして与えられるファイル名。
Path 現在のディレクトリのパス。
Args コマンドラインからインタプリタに渡される初期の引数。
Do-arg コマンドラインで --do オプションに対して与えられた引数。

system/optionsオブジェクトは、コマンドラインで与えられる、この他のオプションも持っている。例えば、次のようにタイプしてみよう:

probe system/options

こうタイプすると、optionsオブジェクトの内容を確認出来る。

例えば:

print system/options/script
probe system/options/args
print read system/options/home/user.r

4. Running Scripts (スクリプトを実行する)

スクリプトを実行する方法は2つある: REBOLインタプリタが起動した時のイニシャルスクリプトとするか、あるいはdo関数から実行するかだ。

インタプリタが起動したときにスクリプトを実行するには、コマンドラインで、REBOLプログラムの名前に続けてスクリプト名を書けば良い:

rebol script.r

インタプリタの初期化の後に、スクリプトが評価される。

do関数から実行するには、スクリプトのファイル名かURLを引数として与える。ファイルがインタプリタに読み込まれ、評価される:

do %script.r

do http://www.rebol.com/script.r

do関数は、スクリプトの評価が終わった時、結果を返す。

スクリプトには、妥当なREBOLヘッダが書かれていなければいけないことに注意しよう。

4.1 Loading Scripts (スクリプトの読み込み)

スクリプトファイルはload関数によって、データとして読み込むことも可能だ。 この関数はスクリプトを読み込み、スクリプトを値、ワード、そしてブロックに変換する。だが、スクリプトの評価は行なわない。 load関数の結果は、単一の値のみが読み込まれたので無い限り、ブロックであり、その値が返される。

load関数に対するスクリプトの引数は、ファイル名、URL、あるいは文字列だ。

load %script.r
load %datafile.txt
load http://www.rebol.org/script.r
load "print now"

load関数は、次のようなステップを実行する:

  • ファイル、URL、あるいは文字列からテキストを読む。
  • スクリプトヘッダを探す。もしあれば。
  • ヘッダの後から始まるデータを変換する。もし見つかれば。
  • 変換された値によるブロックを返す。

例えば、buy.rというスクリプトが次のテキストを含んでいたとしよう:

Buy 100 shares at $20.00 per share

これは、次の行のように読み込むことが出来る:

data: load %buy.r

その結果、次のようなブロックが返される:

probe data
[Buy 100 shares at $20.00 per share]


上の"Buy"の例はREBOLのdialectであり、直接的に実行可能なコードではないということを書いておかなければならない。 詳細は、4章のExpressionsおよび15章のParsingを参照のこと。

読み込まれるファイルには、ヘッダは必須ではないことに注意しよう。 スクリプトとして実行されるファイルにのみ、ヘッダは必須だ。

load関数はいくつかのリファインメントをサポートしている。 load Function Refinmentsに、リファインメントの一覧、およびそれらの機能の説明がある:

/header
ヘッダが存在すれば、それを読み込む。
/next
次の値のみを読み込む。一回に一つの値ずつだ。これはREBOLスクリプトのパージングを行なうのに役立つ。
/markup
ファイルを、HTMLあるいはXMLファイルとして扱い、そのタグとテキストからなるブロックを返す。

通常、loadは、スクリプトからヘッダを返すことはない。しかし、/headerリファインメントを使えば、その最初の引数としてヘッダオブジェクトからなるブロックを返す。

/nextリファインメントは、次の値を読み込み、2つの値からなるブロックを返す。 1つめの値はseriesの次の値である。 2つめの値は、今読んだところに続く文字列の位置だ。

/markupリファインメントは、HTML、あるいはXMLのデータをタグおよび文字列からなるブロックとして読み込む。 すべてのタグはtag data typeである。 それ以外のデータは文字列として扱われる。

次のファイルの内容がload/markupで読み込まれたとしよう:

<title>This is an example</title>

すると、次のようなブロックが生成される:

probe data
[<title> "This is an example" </title>]

4.2 Saving Scripts (スクリプトをセーブする)

データは、load関数によってREBOLに読み込むことが可能な形式として、スクリプトファイルに保存することが可能だ。 これはデータの値や、値のブロックをセーブするのに便利な方法だ。 個のやり方だと、小さなデータベース全体を作ることが可能になる。

save関数は2つの引数を要求する: ファイル名と、セーブされるブロックあるいは値だ:

data: [Buy 100 shares at $20.00 per share]

save %data.r data

The data is written out in REBOL source text format, which can be loaded later with:

データは、後に読み込み可能な、REBOLのソーステキストフォーマットで書き出される。

data: load %data.r

単なる値もセーブできるし、ロードも可能だ。例えば、日付は次の様にセーブできる:

save %date.r now

そして、後で読み込む時にはこうすれば良い:

stamp: load %date.r

先の例では、日付は単一の値だったため、ロードする時にはブロックとはならない。

ヘッダ付きのスクリプトファイルをセーブするには、リファインメントにおいて、オブジェクトあるいはブロックとしてヘッダを与えられる:

header: [Title: "This is an example"]

save/header %data.r data header

4.3 Commenting Scripts (スクリプトへのコメントづけ)

コメント付けはスクリプトの特定の部分の目的を明確にするために有益だ。スクリプトヘッダは、スクリプトの高レベルの説明を提供し、コメントは関数の簡単な説明を提供する。あなたのコードのほかの部分に対してコメントをつけるのも、同様に良いアイディアだ。

一行のコメントは、セミコロンで示される。セミコロンの後、行の終わりまでがコメントになる:

zertplex: 10   ; set to the highest quality

あなたは、文字列をコメントに使うことも出来る。例えば、ブレースで括ることで、複数行のコメントを書くことも出来る:

{
    This is a long multilined comment.
}

コメントをつけるこのテクニックは、文字列が関数の引数として解釈されない場合にのみ有効だ。あなたが、複数行のコメントをコメントとして認識されるようにし、コードとして解釈されないようにすることを確実にすることを望むならば、commentというワードを文字列の前に付けよう:

comment {
    This is a long multilined comment.
}

このcomment関数は、それに続くブロックおよび文字列を無視するようにREBOLに指示する。文字列あるいはブロックによるコメントはスクリプトブロックの一部であることに気をつけよう。それらがデータブロックの中に現れないように十分注意しよう。なぜなら、データの一部として現れてしまうからだ。

5. Style Guide

REBOLスクリプトは自由形式だ。 あなたはインデント、スペーシング、一行の長さ、そして改行コードを好きなように使ってスクリプトを書くことが出来る。 あなたは個々のワードをそれぞれ別の行に書くことも出来るし、逆にそれらを全て長い一行にまとめることも出来る。

あなたのスクリプトの形式がインタープリタに影響を与えることはないとはいえ、人間にとっての読みやすさには影響を与える。 だから、REBOL Technologiesは、以下に示すような標準的なスクリプティングスタイルにあなたが従うことをお勧めする。

もちろん、これらの提案のいずれであれあなたが従わなければならないわけではない。 しかし、スクリプティングスタイルは、一見したよりも重要なものだ。 スクリプトの可読性と再利用において大きな違いをもたらす。 ユーザは、あなたのスクリプトを、そのスタイルの明快さの質で判断する。 ずさんなスクリプトは、ときにずさんなコードを意味する。 経験を積んだスクリプトの書き手は、明快で一貫性のあるスタイルが、彼らのコードを書くことや、メンテナンスや、改訂を容易にすることを知っている。


5.1 Formatting

REBOLスクリプトのフォーマッティングに関する以下のガイドラインを、明快さのために使おう。

5.1.1 Indent Content for Clarity

ブロックを囲むスクエアブラケット [ ] 以外のブロックの中身はインデントされる。 これは、スクエアブラケットは統語上、一つ上のレベルに属しており、ブロックを定義するものであり、ブロックの内容ではないためだ。 同様に、ブラケットが目立てば、隣接するブロックの間の区切りも見つけやすくなる。〔訳注:この一文、たぶんこういう意味〕

可能な場所では、開きスクエアブラケット〔訳注:[〕は、それと関連する式と同じ行に残そう。 閉じブラケット〔訳注:]〕には、それと同じレベルの式が続いてもかまわない。 これと同じルールを、パーレンシス ( ) およびブレース { } にも適用する。

if check [do this and that]

if check [
    do this and do that
    do another thing
    do a few more things
]

either check [do something short][
    do something else]

either check [
    when an expression extends
    past the end of a block...
][
    this helps keep things
    straight
]

while [
    do a longer expression
    to see if it's true
][
    the end of the last block
    and start of the new one
    are at the WHILE level
]

adder: func [
    "This is an example function"
    arg1 "this is the first arg"
    arg2 "this is the second arg"
][
    arg1 + arg2
]

本来であれば一行に属するような式が、複数行に亘るような場合に、例外が役立つ。

if (this is a long conditional expression that
    breaks over a line and is indented
)[
    so this looks a bit odd
]

一行に収めなければならない場合を除いて、これは、一まとめにされたグループドヴァリューにも適用される。

[
    "Hitachi Precision Focus" $1000 10-Jul-1999
        "Computers Are Us"

    "Nuform Natural Keyboard" $70 20-Jul-1999
        "The Keyboard Store"
]
5.1.2 Standard Tab Size

REBOLの標準的なタブサイズは半角スペース4文字文だ。 異なったエディタを使う人や、スクリプトの読み手のために、タブではなくスペースを使うようにしよう。

5.1.3 Detab Before Posting

タブ文字(ASCIIコード 9)は、多くの読み手やシェルにとってスペース4文字分になるとは限らない。そこで、エディタやあるいはREBOLを使って、ネットに公開する前にデタブしよう。 次の関数は、タブを標準的なスペース4文字分にデタブする:

detab-file: func [file-name [file!]] [
    write file-name detab read file-name
]
detab-file %script.r

次の関数は、8文字タブを4文字タブに変換する:

detab-file: func [file-name [file!]] [
    write file-name detab entab/size read file-name 8
]
5.1.4 Limit Line Lengths to 80 Characters

読み易いように、またエディタやemailリーダの間でのポータビリティのために、一行を80文字〔訳注:もちろん半角でだ。〕以下にしよう。 長い行は、emailクライアントによっておかしなところで折り返され、読みにくくなるし、読み込みの際に問題になる。

5.2 Word Names

ワードは、あなたのコードにユーザが最初に接するものだ。 だからワードを慎重に選ぶことはとても重要だ。 スクリプトは明快で簡潔でなければならない。 可能ならば、ワードはその英語あるはその他の人間の言語に、単純に、かつ直接的に関連づいているべきだ。

以下に、REBOLにおける名前付けの習慣的な標準を示しておく。

5.2.1 Use the Shortest Word that Communicates the Meaning

可能ならば、短く、簡潔なワードが良い:

size  time  send  wait  make  quit

局所的ワードは単独のワードに短くされることもある。 より長く、説明的なワードは大域的ワードに適している。

5.2.2 Use Whole Words Where Possible

ワードとして省略したものを使う価値はまずない。 dtではなくdateと、imgflではなくimage-fileと入力しよう。

5.2.3 Hyphenate Multiple Word Names

標準的なスタイルではハイフンを使い、文字の大文字小文字の別は使わない。

group-name image-file  clear-screen  bake-cake
5.2.4 Begin Function Names with a Verb

関数の名前は、動詞で始まり、名詞や副詞、あるいは形容詞が続く。 ある種の名詞は動詞として扱ってかまわない。

make  print  scan  find  show  hide  take
rake-coals  find-age  clear-screen

不要なワードは使わないようにしよう。例えば、quitはquit-systemと同程度に明快だ。

名詞を動詞として扱う場合、?のような特殊文字を使えるなら使おう。 例えば、seriesの長さを得る関数はlength?だ。 その他のこの手のREBOL関数もこの名前付けの習慣にしたがっている:

size?  dir?  time?  modified?
5.2.5 Begin Data Words with Nouns

オブジェクトやデータを保持する変数を示すワードは名詞で始めよう。 修飾語(形容詞)が必要ならそれを含んでもかまわない:

image  sound  big-file  image-files  start-time
5.2.6 Use Standard Names

REBOLには似た種類の操作に使われている標準的な名前がある。例えば:

make-blub           ;creating something new
free-blub           ;releasing resources of something
copy-blub           ;copying the contents of something
to-blub             ;converting to it
insert-blub         ;inserting something
remove-blub         ;removing something
clear-blub          ;clearing something

5.3 Script Headers

ヘッダを使うことの利点は明らかだ。ヘッダはスクリプトのサマリをユーザに提供し、他のスクリプトが情報を処理することを可能にする(カタログ作成スクリプトのように)。 最小限のヘッダでは、titleとdate、file nameとpurposeを書くようにしよう。 他のフィールド、例えばauthor, notes, usageも書いてみよう。


REBOL [
    Title: "Local Area Defringer"
    Date:  1-Jun-1957
    File:  %defringe.r
    Purpose: {
        Stabilize the wide area ignition transcriber
        using a double ganged defringing algorithm.
    }
]

5.4 Function Headers

関数についての記述を書いておくことも役に立つ。 それらのテキストは、一行は70文字以下でなければならない。 説明の中では、関数の返り値のタイプに言及しよう。

defringe: func [
    "Return the defringed localization radius."
    area "Topo area to defringe"
    time "Time allotted for operation"
    /cost num "Maximum cost permitted"
    /compound "Compound the calculation"
][
    ...code...
]

5.5 Script File Names

ファイルに名前をつける一番いい方法は、どうすれば数ヵ月後にきちんと見つけられるかを考えることだ。 短く、明快な名前が概ね良い。 特に意味が無い限り複数形は避けよう。

さらに、スクリプトに名前をつける時には、ディレクトリの中で名前がどのようにソートされるかも考えよう。 例えば、関連したファイルは共通のワードで名前が始まるようにしよう。

%net-start.r
%net-stop.r
%net-run.r

5.6 Embedded Examples

そのスクリプトをどのように使うかの例をスクリプトの中の適切な場所に記述しよう。そしてユーザに彼らのシステムでスクリプトが正しく動くかどうかをすばやく検証できるようにしよう。

5.7 Embedded Debugging

スクリプトの一部としてデバッギング機能を組み込んでおくことは、便利な場合がある。 特にネットワークやファイルの操作を行なうスクリプトで、テストモードにおいて実際にデータを送ったりファイルを書いたりしたくないような場合には。 それらのテストはスクリプトの最初の部分で制御変数として有効に出来るようにしておこう。

verbose: on
check-data: off

5.8 Minimize Globals

大きなスクリプトで、かつ可能な場合は、あるモジュールや関数から別のモジュールや関数へ内部状態を渡すような大域変数の使用は避けよう。 短いスクリプトでは、それらは実用的ではない。 ただし、短いスクリプトは時間とともに長いスクリプトになっていくかもしれないことを覚えておこう。

もし、関連した大域変数の集まりがある場合、それらを一まとめにするためにオブジェクトを使うことを検討しよう:

user: make object! [
    name:  "Fred Dref"
    age:   94
    phone: 707-555-1234
    email: dref@fred.dom
]

6. Script Cleanup

スクリプトのインデントを清書する短いスクリプトがある。 このスクリプトは、REBOLの文法にそってパージングし、スクリプトの各々の行を再構築する。 この例はwww.REBOL.comの REBOL Script Libraryで見つけることが出来る。

out: none ; output text
spaced: off ; add extra bracket spacing
indent: "" ; holds indentation tabs

emit-line: func [] [append out newline]

emit-space: func [pos] [
    append out either newline = last out [indent] [
        pick [#" " ""] found? any [
            spaced
            not any [find "[(" last out
                     find ")]" first pos]
        ]
    ]
]

emit: func [from to] [
    emit-space from append out copy/part from to
]

clean-script: func [
    "Returns new script text with standard spacing."
    script "Original Script text"
    /spacey "Optional spaces near brackets/parens"
    /local str new
] [
    spaced: found? spacey
    out: append clear copy script newline
    parse script blk-rule: [
        some [
            str:
            newline (emit-line) |
            #";" [thru newline | to end] new:
                (emit str new) |
            [#"[" | #"("]
                (emit str 1 append indent tab)
                blk-rule |
            [#"]" | #")"]
                (remove indent emit str 1) |
            skip (set [value new]
                load/next str emit str new) :new
        ]
    ]
    remove out ; remove first char
]

script: clean-script read %script.r

write %new-script.r script

Updated 15-Apr-2005 - Copyright REBOL Technologies - Formatted with MakeDoc2

  • Translated 16-July-2009
Personal tools