先日Xのフォロワーさんとやりとりしていた内容を整理・加筆したものになります.
内容は該当箇所で指摘する一部を除いてiOS17とiOS18で同じです.
iOS18では一部のアクションの説明がiOS17と比べて簡略化されているため、問題ないと判断したものはiOS17での画像を使用しています.
※価格は記事執筆時のものです. 現在の価格はApp Storeから確認ください.
レビュー時のiOSバージョン : iOS18.0
スポンサーリンク
ショートカットのことを改めておさらい
ショートカットはもともとは2014年にリリースされたWorkflowというアプリとして登場しました.
有料な上日本語には対応していませんでしたが2017年3月にAppleが買収し、標準アプリにまでなりました.
予め用意された「アクション」を組み合わせてそれを連続実行することで、本来個々に行う処理をワンタップで行うことができます.
入出力
すべてに言えることではないですが、ショートカットアプリは「関数型プログラミング」という種類に属するローコードプログラムで、ひとつのアクションはおおまかに
入力→処理→出力
という構成になっています.
例えば画像は「テキストを置き換え」というアクションです.
このアクションの場合は3つの入力に加えて2つのオプションを持ち、テキスト形式で出力します.
(これ以降はショートカットに倣って「出力」を「結果」と呼びます)
入力はその場で手打ちする場合と後述の変数のみの場合があり、前者は変数を混ぜることも可能です.
また入力はそのアクションの上に位置する任意の変数を利用できます.
アクションによっては、用意された入力が空でも機能する場合があります.
結果は(存在するならば)そのアクションが実行された直後に、後述する「マジック変数」のひとつとして出力されます.
これらの結果はその後ろにある任意のアクションの入力として使うことができます.
各々のアクションは検索して出てきた右端のiアイコンか、既に追加したアクションのロゴをタップして「情報を表示」を選択すればその説明が表示されます.
他の言語同様、入出力が必ずあるわけではありません.
前置きしたように、iOS18の場合説明から結果などの記述が省略されているアクションがちらほらあります.
問題ないと判断したのでしょうかね.
変数
変数とは、データを入れておく箱のような存在です.
変数にデータを入れたり参照したり、計算に使ったりできます.
しかしショートカットにおける変数はこれに追加された意味合いを持ちます..
例えば「変数を設定」のアクションに書かれている説明の通り、ショートカットのこのアクションは変数と銘打っていますが実際は処理を伴う関数です.
ショートカットでは複数の変数が存在します、順を追って説明します.
マジック変数
上で説明した通り、アクションによっては結果が出力されます.
これらはそのアクションの後ろの任意のアクションの入力として使うことができ、これをマジック変数と呼びます.
後述する「変数」も似たような存在ですが、こちらはデフォルトで変数名が統一化されています.
マジック変数は手打ちが可能の場合、キーボード上部に表示されます(①).
手打ちができない場合は代わりにメニューが表示されるので、ここから「変数を選択」を選び、任意のアクションの結果を選ぶことになります(②).
手打ちの場合でもキーボード上部に「変数を選択」の項目があります(③).
変数名
マジック変数の変数名は上で触れた通りデフォルトで振られていますが目的な便利のために好きな名前にしたい場合があります.
追加したマジック変数をタップして出てきたメニューにある「変数名」の欄に好きな文字列を入れることで、そのマジック変数の名前を変更できます.
こうして変更したマジック変数の変数名は他で使用されている同じマジック変数の変数名に置き換わります.
変数を設定
「変数を設定」は、プログラミングで変数を代入する操作とほぼ同じ役割を持つアクションです.
任意の入力に対して変数名をつけることができます.
入力に入れることができるのはマジック変数のみで、手打ちはできません.
ショートカットは動的型付けに見える静的型付け寄り
我々は「1」だったり「あ」だったりという文字を見てそれが数であるかテキストであるか…を見分けることができます.
しかしコンピュータ上ではいずれもただの文字の羅列としか認識できません.
そんなコンピュータにとってその文字の羅列がどういう種類かを判別するかを決めるのが型(変数型)でありそれを決めることを「型付け」と言います.
言語によっては予め型付けしてコンパイル(ソースコードを機械語に翻訳する作業)する場合と実行時に型の整合性をチェックする場合があります.
前者を静的型付け、後者を動的型付けと言います.
静的型付けはエラーチェックがしやすく、型の整合性をコンパイル時に行うため実行時の処理が速いです.
動的型付けは型付けの手間が不要な分プログラムの行数が少なくて済む一方で実行時に整合性チェックを行うためその分遅いです.
「変数を設定」を実際に使うと、パッと見は変数型の指定がありません.
しかし他のアクションなどでその型を参照するとちゃんと変数型が定まっています(画像の場合は「数字」アクションが対象だったので変数型である「種類」が数字になっています).
これは静的型付けの特徴です.
ただし定まった変数型は対象となる入力(アクション)に依存するため、通常の静的型付けのようにintやstringのような指定は(このままでは)できません(不可能ではないですがアクション数が増えるのでメリットがありません).
そして変数型は使用する入力の場で「種類」を変更することで指定できます.
ここから考えられる特徴は、
- ショートカットアプリの変数は静的型付け
- しかし変数型(種類)は対象のアクションに依存し、「変数を設定」時には変更できない
- 変数型(種類)は使用する入力で変更できる
となります.
変数型の指定が追加時にないので動的型付けに思えるのが厄介ですね.
変数名バグが改善?
自分はマジック変数に変数名を書く派では無かったので気づくのがほんの数日前だったのですが、少なくともiOS17では変数名を書き込んだマジック変数と「変数を設定」で使用した文字列が重複すると、後者が強制的にマジック変数のものに置き換わる現象を確認していました.
iOS18.0では今のところそのような現象は起きていません.
とはいえ今後同じことが起こる可能性はゼロではありませんから気をつけた方がいいです.
このような物事をややこしくさせる命名規則はそもそもするべきでないですけどね.
ちなみにiOS17では「変数を設定」で追加したアクションのアイコンが黄色でxのアイコンでなくグレーの#になるバグが頻繁に起こっていました.
因果関係は不明ですが関係してそうですね.
「変数を設定」と「変数名」どちらを使うべきか
「変数名」はマジック変数をそのまま使うので「変数を設定」の分だけアクションが減り、実行時の負担が減るメリットがあります.
なら「変数を設定」は不要でしょうか?
単純に入力として使う目的ならどちらを使っても問題ないです、そういう目的だけならばわざわざ「変数を設定」を使うメリットはないので変数名を使ったマジック変数で十分です.
変数名によるマジック変数が通用しない例を挙げてみます.
画像は初期値0の数を使って5回の繰り返し処理で1足し続けた結果を出力するレシピです.
「変数を設定」を使う場合は画像のようになります.
繰り返し処理の最後に計算結果を同一変数であるvalueで上書きしています.
ではこれを「変数を設定」なしに、変数名を変えたマジック変数で実現できるでしょうか?
取り除く箇所は上画像の赤く囲った「変数を設定」です.
繰り返し最後の上書きで使う「変数を設定」は避けられないのでこれはこのままです.
理屈の上ではマジック変数も上書きで使う変数も同一の名前にしないといけません.
実行結果は画像の通りです.
繰り返しの最後で上書きしたつもりでも、マジック変数の結果は同一なので実現できず、どの繰り返しでも計算式は0+1をしているわけです.
その結果得られた値は5でなく1になったわけです.
つまりこのレシピの場合、初期値として「変数を設定」を使うことは避けられないということですね.
また、「変数を設定」などの変数の名前とマジック変数の変数名が重複している場合、後者が優先されるようです.
整理すると、変数名を変えたマジック変数は
- 変数名を変えたマジック変数
→アクション数が少なくて済む
→上書きや更新には使えない - 「変数を設定」
→上書きや更新に使える
→アクション数が増える - 通常の変数の名前とマジック変数の変数名が重複した場合、後者が優先
となります.
目的に応じて使い分けると良いですね.
変数に追加
「変数に追加」は「変数を設定」に似ていますが、そちらと異なりこちらのアクションでは配列として入力を格納します.
先程のレシピを使い、結果を表示する代わりに「リストから選択」を使ってみます.
そのままの場合では変数は上書きしたので項目数はひとつですから当然選択肢はひとつしかありません.
同じレシピで繰り返しでの計算結果を「変数に追加」で格納し、その結果を「リストから選択」で呼び出してみます.
この場合繰り返した分だけデータが追加されるので、その分だけ選択肢が出てくるようになりました.
入力がテキスト(数)か配列か…で結果が異なるアクションがあるので注意する必要があります.
配列状態のデータを単一のテキストにするには「テキストを結合」で改行で結合するといいです.
逆に「テキストを分割」は入力のデータを配列化します.
変数を取得
「変数を取得」は、指定した変数の値をそのまま出力するアクションです.
変数の扱いに富む更新をし続けたショートカットでは特に使う機会がない…というか、わざわざ使うことのないアクションです.
編集画面で入力にどの変数が使われているかが明確になる…くらいのメリットしかないですね、それも該当アクションの入力に追加した変数の命名がわかりやすく付けられていれば無用ですし.
マジック変数に慣れていない場合に使うといいかもしれません.
〆
今回のやり取りをきっかけに気づけたのは変数名を変えたマジック変数のデメリットでした.
アクション数を増やさずに済む一方上書きや更新に使えないのは性質上仕方ないと思いつつ勿体ないな…と.
フォロワーさんとやり取りした結果事前に変化や違和感に気づけて良かったです.