見出し画像

デフォルトブラウザ「以外」でWebページを複数開く 〜AppleScriptとの連携〜【後編】

前編はこちら。

前回でワークフロー全体は完成しました。
この後編では、プログラミングに多少なりとも興味のある方へ向けた、その一般的な概念なども織り交ぜた AppleScript コードの説明をしてみようと思います。


プログラムに餌を与える

コンピュータに何をしてほしいかと言ったら、今回は複数のサイトを一気に(タブで)開いてほしいということ。

まずは、その複数の「データ」を用意したのが、最初のアクションである「指定された URL を取得」。例としてこのように3サイトほど設定しました。皆さんの環境では、追加ボタンを押しつつお好きなサイトのURLを書き込んでください。

画像1

単一のURLを一つのデータとして見たとき、それをいくつか含んだひとまとまりのデータを AppleScript では「リスト」と呼びます。一般的な言語では「配列」などと呼ばれます。

さてこのリスト。
イメージとしてはよくこんなメタファーが使われます。データ一つ一つが納められた「箱」、それが連結したもの。

画像5

この図中の一つ一つの箱は、後ほど説明する「変数」と呼ばれるものです。リストそのものも変数ではあるのですが、区別のために、単独データなら「変数」、複数が連結したものが「リスト」、としておきます。

今回のプログラムにはトピックとして直接関係ないものの、これもイメージとして掴んでほしいことが図の中にあります。
下側に書き加えたように、一般的にリスト(配列)は、定義した順番が保持されます。箱の左側を先頭としましたが、上下に積み重なったものを想像してもらってもかまいません。

定義ってどゆことですか。はい、それはつまり最初のアクション「指定された URL を取得」でURLの文字列を列挙することと同時に3つのURLの上から下への順番を決めた、あの作業のことです。

これは AppleScript 側でもできることです。こんな風に書きます。(改行は本来しません)

set theList to {
 "https://www.apple.com/jp/",
 "https://www.yahoo.co.jp/",
 "https://www.google.co.jp/"
}

直接関係のない話題なので、眺めておいてくれれば良いです。

また今回は必要が無いため、特に順番を意識せずにこのリストを使用しているのですが、もしプログラムの中で指定して取り出したい場合は図の下のようにします。

item 添字 of リスト(名)

添字という言葉が出てきました。「インデックス(index)」もしくは「配列インデックス」などが一般的な呼称です。
リストから特定の場所のデータを取り出すために必須の概念です。ここには順番(位置)指定のための数値が入ります。
これもここでは行っていないのですが、通常はリストを定義する時に、上の例のように(「theList」としました)そのリストの名前を決めます。このアクションの連結の中で、特別に、そう貴方だけに特別に、無名のリストが許されています。

添字はそのリスト名と組み合わせて上のように使います。あるリストの何番目のアイテム、と指定する。なんだめちゃめちゃわかりやすいですね。
今回は3つのURLデータがあるので、1,2,3のどれかの数値で指定すると該当のデータが取り出せる。上の例ならこんな感じです。

item 3 of theList
→ "https://www.google.co.jp/" が取り出される

それ以上の数を指定するとどうなるか? エラーが出てプログラムが動きません。\( ̄▽ ̄)/

この添字に関して、さらに言っておかなければならないことがあります。
ほとんどのプログラミング言語では、この添字(インデックス)は「0(ゼロ)」から始まります。リスト(配列)の先頭のデータを取り出すときは「リスト名[0]」のようになります。その方が一般的なので、この部分、AppleScript は特殊であると覚えておいてください。

ちょっと、いやかなり脱線しました。
いま、最初のアクションでURLを3つ用意し「AppleScript を実行」アクションに送りました。アクションの連結によって、送る動作は自動的に行われていきます。次いきましょう。



関数という、自動販売機

データを「はい、これ」と渡すと、何か意味のある仕事をしてくれる。
それが関数の役割です。ちょうど、お金を入れボタンを押すと飲み物が出て来る自販機のように。

この「関数」という言葉自体は皆さん知っていることでしょう。
表計算ソフト「Excel」における SUM関数などがそれにあたりますね。

そのSUM関数は、どういう姿をしているでしょうか。

SUM(A1:A3)

このように、SUMという関数名の直後に括弧があり、入力を受け付けるようになっているのがおわかりかと思います。
この場合はセルの場所を書き込むことにより、その範囲の数値の合計が求められる。

入力を求め、何かしらの結果を出力として返す。
これが関数というもので、殆どの場合の基本的な構造になっています。

その他の場合というのは、関数が入出力をせずに、ある振る舞いだけをして終了、など。
ブラウザで言えば、ボタンを押すと色や形状が変化してみたり。付随して他のパーツの文字も変化させたい時にそれらの動きを関数にまとめておくというようなケースがあります。

今回の AppleScript コードはそのまま関数の形をしています。
では俯瞰していきましょう。コード全体はこのようなものでした。

on run {input, parameters}

	--set webBrowser to "Google Chrome"
	set webBrowser to "Firefox"

	repeat with theURL in input
		tell application webBrowser to open location theURL
	end repeat

	return input

end run

まず先頭行の「on run 〜」。
on キーワードは、まさに関数を宣言・定義するためのものです。「on 関数名」という形。
そして、「end 関数名」で、この関数ブロックを閉じます。

この関数名「run」は予約語で、既に AppleScript の中で決められているものです。
これまで、アプリケーション形式でワークフローを保存したりしましたが、ダブルクリックによる起動などにより自動的に実行される・してほしい動作を記述するのに使います。

通常、関数名は自分で好きなように決めることができますが、逆に今回はその必要がないということです。短いコードということもあり、この run ブロックに収めていれば全てのコードが実行されます。

画像4


データを収めておく「箱」

前述の「on run 〜」で、関数の宣言をし、ブロックができました。最初から書き込まれていましたけれど。 笑
この関数は、上のアクションから渡されたデータを「input」という変数で受け取ります。
on run の直後に波括弧がありますね。これが先のSUM関数の括弧の例と同様に働きます。

関数においては入力を受けるこの部分の変数を特別に「引数(ひきすう)」と呼びます。英語ですとここにあるように parameters や arguments などと呼ばれます。…という知識だけでまずはOK。

そして、次の、2,3行目で違う形の、いえ、変数としてはごく一般的な使い方の例が出て来ます。

画像3

変数とは、データを保管するための箱。
ここでは自分でその箱を作りました。input変数のように用意されたものではなく。

set 変数名 to 値

作法はこうです。自分で自由に決めた変数名。そこにある値を「セット」する。
上でリストの定義の方法をチラ見しましたが、変数定義の記述はすべてこの形になります。
AppleScript は自然言語に近い書き方ができるので、どれをとっても意味がわかりやすいのではないでしょうか。

変数名は値の属性を抽象化してつけるのが一般的です。なにより、自分自身で後からコードを見た時にわかりやすい。
動作させるブラウザの名前を保持しておきたかったので、webBrowser としました。そこに文字列を入れるわけですが、この操作自体を「代入」と言います。

今回は文字列の代入なので、値を「ダブルクオートで囲む」という決まり事があります。
日本語で自分の氏名などを代入しておきたければ、やはりそうなります。
ここで宣言した変数は勿論、この後使われます。

ちなみにこの変数宣言と代入、他の言語ですとシンプルに

(接頭辞) 変数名=値

のようにイコールで書かれることがほとんどです。
接頭辞とあるのは、今は気にしなくて良いですが、他の言語のコードを見ることがあれば比べてみると良いかもしれません。


さて、また脱線します。
変数を作り、そこへは主に数値や文字列のデータが入りますが、それを代入することで、いったい何が嬉しいのか

今回のプログラムは、このようにも書けます。

画像6

特に変数を作ったり代入しなくても「直接」置いておける。
じゃあなぜわざわざそれをするか。

その理由は、コードが長くなった時を想像してもらえるとわかります。
ここではほとんどの変数は1度しか出現しませんが、コードの機能、規模、行数が多くなってきて、同じブラウザ名をコードのあちこちで使わなければならなくなった時。

例えば使うブラウザを変更したいとします。
一度変数にブラウザ名を代入しておいて、その変数の方を使うようにすれば、変更がひと手間で済みます。
ダブルクオートで囲んだ文字列がコードのあちこちに散在していると、全部を修正しなければなりません。そういう事態を避けるというのが大きな目的です。

また副産物としては、初期設定のような役割を果たすということが言えます。
先に書いたように変数名をわかりやすく付け、関数の先頭行で定義してまとめておくと、コード全体の見通しもすっきりとする、そんな効果もあります。
こういったことは、コードを多く書くと自然と身につくことですが、今から意識しておいて損はないかと思います。


処理を繰り返す 〜ループ〜

さて、このワークフローの動作の核となるのが、次の「repeat 〜 end repeat」で囲まれたブロック。

画像4

ここで繰り返しの処理をします。一般に「ループ」と言われる制御構造を作り出すもので、どんな言語にも備わっている機構です。

構文「repeat with X in Y」は、Yという名前のリストの中から、一項目づつXに取り出してきて操作をする、というもの。

無限ループ、という言葉を聞いたことがある人は多いかもしれません。ここでは、リストの長さ(含むデータ個数)は最初に3つと決めたので、個数ぶんの処理が終われば停止します。そういった条件が崩れると無限になってしまうわけですね 笑

④と番号を振った変数、ループの中では一時変数などと言いますが、いきなり宣言してかまわないのでそう呼ばれます。これも自由に名前を付けることができますが、やはり後で使うので属性を反映した名前にすべきです。リストから取り出した単独のURLという意味で「theURL」としています。

リストはデータを定義した順番を保持している、と上で書きました。
この繰り返し構文は何も指定しないので、素直に先頭から順番に処理されるのがわかると思います。興味があれば、最初のアクションで書いたURLの順番を入れ替えてみてください。(ドラッグすると移動できます)


アプリケーションに話しかける

ループのブロックの中の「tell」で始まる行こそが、Webブラウザに直接命令を伝えるコードになります。

本来これは tell ブロックとして「tell 〜 end tell」とする必要があるのですが、単一の操作のみなら省略可となり、このような見た目になっています。

tell (対象の種類 *1) (対象の名前 *2) to (命令 *3) (命令に必要なデータ *4)

tell が処理対象とするのはアプリケーションだけではない「モノ」も含まれますが、(*1) ではそのまま予約語である application と入り、その名前は上の行で変数 webBrowser に代入しておいたブラウザの名前 (*2) 。

Chrome の行をコメントアウトしているので Firefox がページを開きます。コメントアウトを逆にすれば Chrome の担当。

例として同じ文を2行書き、スイッチできるようにしましたが、わかりますかね。どちらかが不要ならば削除してかまいません。勿論、皆さんの環境に存在するブラウザの名前をダブルクオートの中に書き込んでおいてください。

ただ気をつけないといけないのは、to に続く命令 (*3) の記述が、ブラウザによって違う場合があるということ。ここでは共通ですが、AppleScript の場合そういうことがあり得るので知っておいた方がいいでしょう。

最後にデータ (*4) 。後から使用すると言っていた「theURL」ですね。ループが一度回るたびに、ここにそれが渡され、結果命令が完全なものになり、ページが開かれるというわけです。勿論同じ名前にしておかなければ参照されません。タイプミスなどなきよう。 笑


AppleScript こぼれ話
そもそもの話として、AppleScript に対応する、つまり AppleScript プログラミングによる自動運転ができるような命令セットを作るかどうかは、各ソフトの開発元に任されているのです。
open location は URL を指定しページを開く命令ですが、そんな理由があるので、同じ動作でも各ソフト(ブラウザ)で記述が異なるということはあり得る、というわけですね…


ハッピーエンド

先に言ったとおり、今回は3つのURLデータがリストになったものを処理し、それが尽きれば停止します。成功しましたか?

繰り返しの処理、つまりタブを開き順次サイトを表示していく速度は、コンピューターの処理能力によって変わり、出来得る限り高速に行われます。
ですが、処理が終了する前に不意に何か割り込みが入ると思いがけない動作になる可能性もあるので、数十サイトなどあまりに多いのはちょっと…という感じではあります。 笑

短いコードの割に記事が長くなりましたが…
一つのURLデータ(リスト)が滑り降り、ループでぐるぐる処理されるという、ウォータースライダーで遊ぶようなイメージを持ってもらえればな、と思いながら書きました。

ではまた。一緒に楽しみましょう♪

この記事が気に入ったらサポートをしてみませんか?