もう一人のY君

iPhoneアプリのレビューやアップデートレビューなどを書いています. たまに数学の記事も書きます.

もう一人のY君 MENU  MENU

【iOS12】ショートカットアプリにある「変数」の違い, 使い方

180924_00

 iOS12で使えるようになったWorkflowの後継であるショートカット, 今回は変数についてです.

 

 

スポンサーリンク

 

 

変数

180924_01

 画面下のボックスから「変数」で検索すると3つ出てきます.

 

 

180924_02

 それぞれの説明を並べると上の通りです.

 

 

変数を設定 
指定された変数の値をこのアクションの入力に設定. 
入力  すべて 
結果  (すべて)入力 

 

変数に追加 

このアクションの入力を指定された変数に追加. その変数が存在しない場合は作成.

これによって1つの変数に複数の項目を含めることができる. 

入力  すべて 
結果  (すべて)変数のアップデート済みの内容. 

 

変数を取得 
指定された変数の値を取得して次のアクションに渡す. 
入力 
結果  すべて 

 

 この説明を見て分かるなら良いのですが独自の言葉もあるせいでイマイチわかりにくいですよね.

 

 

「アクションの入力」とは何か

 そもそもこの言葉がよく分かりません.

 色々弄った結果, これは「ワーキングメモリ(に相当する領域)に一時的に保存されたデータ」を指すようです.

 

 例えれば「電卓のモニタに表示されている値」です.

 この値はその時点では目視によって分かりますしそれを使って計算を続けることは可能ですが, クリアしたり他の演算を行うとそれまでのデータは無くなってしまいますね.

 

 電卓をはじめマイコンでは, 足し算にしろ引き算にしろ, 計算の途中経過を一時的に保存しておく部分がRAMに存在します.

 マイコンによってワーキングメモリとかワーキングレジスタ(wレジスタ)などと呼び方が少し違いますが, 目的は概ね同じで特徴的な性質としては「リセットすると値は0になる」ということです.

 

 まさに実務などで電卓を使うように, 計算結果を一時的に表示して他で使います.

 

 以下本題からずれているように見えるかもしれませんがショートカットを構成する上で特徴が似ているため少し我慢してください.

 難しいと思ったらとりあえず

 

「アクションの入力」とは常にその時点での計算結果のこと

 

とだけ覚えておいてください.

 

 

 例えばPICというマイコンでは足し算の命令の一つとして ADDLW があります, 具体的には

 

ADDLW k

 

と記述し, 全体から見て ADDLW の部分を「ニーモニック」, k の部分を「オペランド」と言います.

 k は「リテラル」と言って具体的な数あるいは文字列を指します.

 この命令は「kとwレジスタを足す」操作を行います.

 

 上でも書きましたがマイコンの中では計算結果を常に一時的にwレジスタに保存しています.

 従って足し算をはじめとする演算というのは数学で言うところの「二元演算」であり, つまり二変数関数

 

{ \displaystyle f(x,y) }

 

と言えます.

 しかしPICをはじめ一部のマイコンはこのように自由でなく, 任意の値同士…の演算, 論理演算でなくwレジスタとリテラル, 定数, アドレスなどとのやり取り, あるいはリテラル等々のみを用いた命令しか行なえません.

 なので例えば2つのレジスタにある値を足し算したい場合, 片方を一旦wレジスタに代入し, wレジスタともう一方のレジスタを足し合わせるという2サイクルの手間がかかります.

 これはPICが元々低価格で簡単な仕様となるよう作られたのが要因の一つで, シリーズによっては命令が35個程度しかないものがあります(より高級になるとメモリの容量も命令も多くなります).

 

 

 余計な話が多くなりましたがいづれにしろこの「アクションの入力」は上記で言うところのwレジスタに相当します.

 現に実際に見れば分かりますが例えば「計算」というアクションは2つの変数 { \displaystyle x, y } を直接計算する仕組みでなく,

 

アクションの入力とオペランド(具体的な数あるいは変数など)

 

 によって行われます.

 

 従って単純に四則演算をしたくてもその手間は例えばC言語などとは違い手数も多くなります.

 ショートカットアプリは見た目こそ簡単そうに見えますが実際はPICのように機械語と1対1に対応するアセンブリ言語に近いのかもしれません(もちろんすべてのアクションがそうではありません).

 

 とはいえ, アセンブリ言語とは全く一致するわけではありません, 少なくとも変数や計算などの一部アクションの話です.

 

 

変数を設定

180924_17

 では本題に入ります, 実際にフローを立てて説明していきます.

 「変数を設定」は

 

  • 変数(名)を定義する
  • 現在の「アクションの入力」の値をその変数に代入する

 

の2つの機能を有します.

 

 例外としてフローの一番はじめの時点では「アクションの入力」には値が入っていないため, いきなり変数宣言をしてもその変数に値は代入されません(Null).

 そのためその後の演算が正しく行われない可能性があります.

 そのため最初に数「1」を立てることで「アクションの入力」に代入しておき, これによって2つ目の「変数の設定」で x に 1 が代入されます.

 場合によっては「入力を要求」のアクションなどでその場で好きな値を入力します.

 

 続いて「計算」を利用して「アクションの入力」(変数xでないことに注意)に1を加えて 2 にします.

 フォームや結果からも分かる通り, 先程のPICの話と同様, 「計算」はwレジスタに相当する「アクションの入力」と, 指定した値であるオペランドによる演算を行います.

 オペランドは具体的な数を入れてもいいですし, 変数を入れることもできます.

 

 次に改めて「変数の設定」で x を宣言すると, それまで 1が代入されていた x に, その時点で 2 になった「アクションの入力」の値が代入され x が2となります.

 

 最後に「結果を表示」で x に代入された値を確認すれば 2 になっていることが分かりました.

 

 このように変数定義については他のプログラムとは性質が異なります, つまり

 

  • 変数は重複して宣言しても良い
  • 代わりに値が変わる(上書き)可能性がある(むしろそれを利用できる)

 

と言えます.

 

 

マジック変数

180924_05

 ショートカットには「マジック変数」という機能があります.

 各アクションで結果が変わったタイミングでの計算結果などを指定することができ,  例えば「結果を表示」でキーボードを開いた際に上側に表示されます.

 本来「計算」での結果を y という変数に代入し, 「結果を表示」で表示する場合と, 同じ計算結果の箇所を「計算結果」で指定した場合…

 

 

180924_06

 得られる結果は同じになるわけです.

 これを使えば余計な変数を増やす必要がなくなります.

 

 

180924_07

 マジック変数は「計算結果」以外にも種類があり, またキーボードを開いた際に上に出てくる左から2つ目のアイコンをタップすると, 現在のフローのうち, マジック変数に相当する箇所にアイコンが表示され, これをタップすることで反映されます.

 なお同じ場所の左端にある「変数」をタップすれば既存の変数やクリップボードなどを選択できます.

 

 

「計算」の処理を変更

180924_15

 「計算」のアクションは表に四則演算が表示されており, 切り替えられますが右端の「…」をタップすることで他の関数に切り替えることができます.

 

 

 

変数に追加

180924_10

 続いて「変数に追加」です.

 これは簡単に言えば「配列」の機能を果たします.

 「変数を設定」では繰り返しても上書きされていきますが, こちらはフローがやってきて処理されるたびにその変数の次の番号に「アクションの入力」の値が代入されます.

 試しに上のようにxという変数に1を代入して定義した後, 直ぐに「変数に追加」を置いて実行してみます.

 

 

180924_11

 すると「計算」の前に「項目を選択」が現れます.

 これは「変数を設定」後に「変数に追加」を行ったため変数xの配列数が2となり, 「計算」を行う上での「アクションの入力」への選択肢が増えたために表示されるものです.

 ようは「どれをアクションの入力に適用するのか」ということですね.

 

 今回は単純に並べましたが間に別の処理があれば異なる選択となることは想像に難くないでしょう.

 

 

180924_12

 またこれも当然ですが同じ変数で「変数に追加」→「変数を設定」に並べれば配列は1つです(いづれか一つで十分).

 

 このように結果を表示することでよく分かりますが, 

 

  • 変数を設定:値を上書き代入
  • 変数に追加:配列として次の項に値を代入

 

という違いがあります.

 そもそも配列と言っても項数を指定しないためある意味では項数を削除できないdequeやvectorに近いのかもしれませんね.

 

 使ってみた印象としては配列でよくある「任意の列の値を参照する」ことは仕様上できないと考えられます.

 また説明からして取り出せる値は一番後ろのみと思われます.

 値を取り出すタイミングを誤ることなく使う必要があります.

 

 

変数を取得

180924_13

 「変数を取得」は, 指定の変数に入っている値を「アクションの入力」に代入します.

 つまり上2つとは逆の関係ですね.

 画像を参考に説明しましょう.

 まず「変数を取得」を使わないフローです, 最初に変数x,yに1を代入して宣言し, 「アクションの入力」に1を足し, その結果を変数zに渡します.

 結果は当然画像右のようにx=1, y=1, z=2になりますね.

 

 

180924_14

 では同じフローで, zにアクションの入力を代入する前にyの値を使って「変数を取得」を追加しましょう.

 すると「変数を取得」によってyの値が「アクションの入力」に上書きされて直前の「計算」の結果が無視され, 続く「変数に追加」でzに代入されます.

 結果 x=1, y=1, z=1 となります.

 

 

 結局ややこしくなってしまった気がしますが, 配列を意識しない作りであれば

 

  • 変数を設定
  • 変数を取得

 

の2つを主に使えば良い…と解釈すれば概ね問題ありません.