Vectorworks」カテゴリーアーカイブ

VectorScriptのインクルード その2

VectorWorksプログラミング実行環境で使える言語「VectorScript」の話。インクルードしたいファイル名を絶対パスで指定するか、相対パスで指定するか、という話(VectorScriptのインクルード その1)の続きです。

普通C/C++などのコンパイル型言語では、コンパイル時にコンパイラーが理解できる相対パスでインクルードするのが一般的。ビルドしてしまえばあとは一体化しているのでプログラムを動かす時はインクルードパスを意識する必要はない。

VectorScriptでも、絶対パスでインクルードファイルを指定するのは無しだと思う。相対パスじゃないと別のマシンで読み込めない。ではインクルードファイルを参照可能な場所とはどこか。

ここではVectorWorksフォルダ(Vectorworksアプリのあるフォルダ)にしてみた。図面ファイルの横に置くと、図面を別の場所に保存するとき、VectorScriptのインクルードするソースファイルもコピーしなくてはならない。Vectorworksフォルダならすべての図面ファイルから参照可能。

メインとなるソースはたとえば次のようになる。

{$INCLUDE xxx}で4つのソースファイルをインクルード

{$INCLUDE xxx}で4つのソースファイルをインクルード。次の図のようにVectorWorksフォルダに「JCLVS」フォルダを置き、ソースファイルとテキストファイルを置いておく。

Vectorworks 2015フォルダに「JCLVS」フォルダ

たとえばダイアログを表示する「My_dlg_2Edit1Cbx.pas」の中身は次。

2つの入力フィールドと1つのチェックボックスを指定するためのダイアログボックスを表示するためのプログラムだ。メインのソースの、{$INCLUDE JCLVS\My_dlg_2Edit1Cbx.pas}のところに「My_dlg_2Edit1Cbx.pas」の中身(231行)が展開されて、構文チェックされる。メインプログラムは飛躍的に読みやすくなった。

メインプログラムの13行目、filenameに「JCLVS\default.txt」を代入してダイアログの関数に渡しいてる。外部ファイル「My_dlg_2Edit1Cbx.pas」のソースから引数でファイル名を渡された「JCLVS\default.txt」を読み込むことができていることにも注目してほしい。

このようにVectorWorksフォルダにソースファイルの一部を置いておくことでメインプログラムの可読性が高まる。メインプログラムを作っている時にうっかりサブプログラムに影響を与えることが減って生産性が高まる。変数のスコープ(有効範囲)を意識して、変数名・関数名にネーミングルールを設けた方がいい。これはソースを分割しない場合でも。

ソースが展開されるだけなので、サブプログラムからメインプログラムの変数は参照できるし、インクルードしているサブファイルが2つ以上あって、両方に同じ関数が定義されているとエラーになるので注意が必要だ。C言語の分割ソースとは異なる。

上記の場合で、たとえばMy_Lib.pasの中で共通ライブラリ「JCL_str.pas」の文字列操作関数を使いたいとする。My_Lib.pasに{$INCLUDE JCLVS\JCL_str.pas}を記述すれば、JCL_strを使えるようになる。が、メインプログラムでも{$INCLUDE JCLVS\JCL_str.pas}が記述されていて二重インクルードのエラーになる。この問題についてはまた次回。

VectorScriptのインクルード その1

知ってましたか?インクルード。VectorScriptの実行環境には、複数のソースファイルに分割して記述されたコードをまとめて実行する機能がある。あ、言い換える、ソースコードを複数のソースファイルに分けて書くことができる。

VectorScriptのスクリプトエディタには貼り付けることのできるコード量の上限があって。は、ひとつのプログラムがソースで32kbytesまで、字数にして32,000文字、全角なら16,000文字、A4に1行に50文字くらいだとして、1ページに60行入るとして、1ページに3,000文字、10ページちょっと。ソースだからステップ数(行数)でいうと600ステップ。えっ、そんなに少ないの?これだとすぐに限界がきちゃう。

VectorScriptでそんなに長いプログラムを書くことがあるのか?という疑問もおありでしょうが、いろいろなプログラムを作っているとすぐにぶつかりますね。特にダイアログ関係はアイテム数が多いとぐんぐんコードが増えていく。図面に色々な図形を自動描画させたりすれば、これもまたコードが増える。プログラマの欲望としてプログラムには1度に大量のことをやらせたいのだ。上限なんてとんでもねえ。

もう一つプログラムが長くなるのがライブラリ化。可読性を高めるために、たとえば文字列切り出しなどの小技なプログラムをfunction/procedureに書いておく。一度役に立ったものは、別のプログラムでも使えるかもしれない。どんどんたまっていく。使うところだけ切り離すのは手間。

そこでインクルード(INCLUDE)の登場。言語によってはimportって記述する。ソースコードを分割して記述できる機能で多くの言語に備わっている。VectorScriptでも実装されている。VectorScriptのスクリプトエディタに貼り付けたメインとなるソースの他に、どこかのフォルダにサブとなるソースファイル(テキスト形式)を置いておいて、コンパイル・実行時に読み込んでくれる。

ということは、メインとなるソースは図面ファイルの中にあって、プログラムの一部が外部のソースファイルにある。図面ファイルだけではプログラムが動かない。

外部にソースファイルを置く、ということはファイルのパス名(通り道の意味のpath)、ファイルパスとか呼ばれている。macOSでは「Macintosh HD:アプリケーション:…..」のようなもの、Windowsでは「C:\….」からはじまっている記述方法、が絶対パス、これに対して「../download」のような一つ上の「download」フォルダ、の意味を示す記述方法、相対パスがある。絶対パスで参照するか、相対パスで参照するか、いずれにしてもこのパス名をソースの中に記述することになる。自分のマシンだけでプログラムを動かすのなら絶対パスでもいいけど、別のマシンでもソースを修正することなく動いて欲しい。そう、マシンが変わったらパス名が違うし、フォルダが変わっても絶対パスは変わる。

VectorScriptのインクルード その2」に続く

VectorScript用のエディタ紹介「Visual Studio Code」

VectorScript用のエディタ紹介です。VectorScriptの文法(Pascal文法)でカラーシンタックスしてくれます。

https://www.microsoft.com/ja-jp/dev/products/code-vs.aspx

Marketplaceで、pascal対応のフリーのextensionを見つけました。

https://marketplace.visualstudio.com/items?itemName=alefragnani.pascal

インストール方法:Visual Studio Code(以下、VS Code)を起動。⌘+Pをタイプして、「 ext install pascal」をペーストしてenterキーを押す。これだけでPascal文法に対応してくれます。

Installation
Launch VS Code Quick Open (⌘+P), paste the following command, and press enter.
 ext install pascal

これでVectorScriptを編集してみると...wonderfull!!!

vscode_vectorscript
インテリセンスも働きます。次々に先行補完がされて、コーディングミスが少なくなります。
注意:ファイルパスの区切り文字が「¥」で保存されていてもutf-8で表示されると「\」になって、このまま保存するとパスが成立しなくなることがあるので注意。上記の例だとデスクトップのパスが心配ですね。スラッシュになってるし。

VectorScriptでデスクトップにテキストファイルを作成

VectorScriptでデスクトップにテキストファイルを作成するスクリプトを作りました。

MacOS X 10.10とWindows7のどちらでも動きます。

{ 関数:Jiro_DesktopPath }
{ 機能:デスクトップのパスを取得する }
{ User App Data 12 }
function Jiro_DesktopPath: string;
const
kDesktopKeyword_Mac = ‘Library’; { ユーザデスクトップパスを得るためのキー }
kDesktopKeyword_Win7 = ‘AppData’; { ユーザデスクトップパスを得るためのキー }
kDelimiter_Mac = ‘:’; { 区切り文字 }
kDelimiter_Win = ‘\’; { 区切り文字 }
var
path: string;
keyword_in_path: string;
delimiter: string;
index: LONGINT;
strLen: LONGINT;
appMajor, appMinor, appMaint, platform :INTEGER;
BEGIN
{ ユーザデータのフォルダを取得、このオプションにはユーザ名が入っている }
path := GetFolderPath( 12 ); { Mac: Library, Win7- : App Data 12 }
strLen:= Len( path );

{ Mac or Win }
GetVersion(appMajor, appMinor, appMaint, platform);
IF (platform = 1) then begin
{ Mac }
keyword_in_path := kDesktopKeyword_Mac;
delimiter := kDelimiter_Mac
end else begin
{ Win }
keyword_in_path := kDesktopKeyword_Win7;
delimiter := kDelimiter_Win
end;

{ キー以降を削除 }
index := Pos( keyword_in_path, path );
IF ( index > 0 ) THEN BEGIN

{ 見つかったらそのあとを削除 }
Delete( path, index, strLen-index+1 );
path := concat( path, ‘Desktop’, delimiter );
END;

Jiro_DesktopPath := path;
END; { Jiro_DesktopPath }