関数内のシングルクウォート連続3個とカンマの意味について
Afficher commentaires plus anciens
cmd = ['load(''',BeforeName,''',''',strjoin(rot90(CheckList,3),''','''),''');']
上記のプログラム解釈についてご教示頂きたいです。
当該プログラムはMファイルとして実行しているプログラムの一部になります。
load関数についてのヘルプを見ると、第1引数から第3引数まではそれぞれ仕様にて定義されていましたが、第4引数以降は仕様としては存在しないと理解しました。
ですが当初自身の上記プログラムの理解としては、第1引数と第3引数、第4引数と第6引数にシングルクウォートを引数として指定しているでしたが、実際にMATLAB上でデバックすると変数cmdには「'load('BeforeName','strjoin(rot90(CheckList,3),','),');'」が格納されていました。
ですので上記プログラムの挙動としては、第1引数はBeforeNameが指定され第2引数はstrjoin(rot90(CheckList,3),',')が指定されていると考えました。
ただそうだとすると、ヘルプページに記載のload関数の仕様と実際の挙動の辻褄が合いません。
もしかすると、シングルクウォートが連続3個記載されている箇所とカンマの解釈次第で当該不整合が解消されるのではと想像しております。
ですので、関数内でシングルクウォートとカンマを使用する際の挙動についてご教示頂きたいです。
またそれが記載されているヘルプページがありましたら、そのページも併せてご教示頂けますと幸いです。
因みに現在の自身の理解では、関数内のカンマは第n引数と第n+1引数(nは1以上の自然数)を区切る以外の機能は持ち合わせていないと思っているのですが、その点につきましても認識に齟齬がありましたら併せてご教示頂けますと幸いです。
もし自身の予想が全くの検討違いだった際は、上記プログラムの正しい解釈方法をヘルプページの解説と併せてご教示頂けますと幸いです。
お手数をお掛けしてしまい大変恐縮ですが、何卒宜しくお願い致します。
Réponses (1)
Atsushi Ueno
le 13 Mar 2023
Modifié(e) : Atsushi Ueno
le 13 Mar 2023
> 第1引数から第3引数までは仕様にて定義されていましたが、第4引数以降は仕様としては存在しないと理解しました
一見、load(filename,'-mat',variables)の様に第3引数まではそれぞれ仕様にて定義されている様に見えますが、variablesは可変個数の引数として定義されているのでこの限りではありません。例えば load 関数を下記の様に使っても問題無く動作します。
load('accidents.mat','datasources','hwycols','hwydata','hwyheaders','hwyidx','hwyrows','statelabel','ushwydata','uslabel')
> 第1引数はBeforeNameが指定され第2引数はstrjoin(rot90(CheckList,3),',')が指定されていると考えました。ただそうだとすると、ヘルプページに記載のload関数の仕様と実際の挙動の辻褄が合いません。
第2引数は可変個数なので、第3引数、第4引数…と続く事が想定されます。具体的には下記の様に文字ベクトルのセル配列が入力される事が想定され、strjoin関数により「 ',' 」で区切られた可変個数の変数になります。一重引用符のエスケープシーケンスが解釈され、変数cmdに文字ベクトルとして格納されます。
BeforeName = 'sample.mat';
CheckList = {'check1','check2','check3'}; % テスト用
cmd = ['load(''',BeforeName,''',''',strjoin(rot90(CheckList,3),''','''),''');']
> もしかすると、シングルクウォートが連続3個記載されている箇所とカンマの解釈次第で当該不整合が解消されるのではと想像しております。
そんな事はないのですが、分かり難いので二重引用符(ダブルクウォート)に変える事が推奨されます。但しこの場合、文字ベクトルはstring型に変わってしまいますので、文字ベクトルのセル配列もstring配列に変更する事になります。詳細な説明は下記リンク先に譲ります。文字と文字列 - MATLAB & Simulink - MathWorks 日本
cmd = ['load("',BeforeName,'","',strjoin(rot90(CheckList,3),'","'),'");']
>関数内でシングルクウォートとカンマを使用する際の挙動についてご教示頂きたいです。またそれが記載されているヘルプページがありましたら、そのページも併せてご教示頂けますと幸いです。
この点は現在の使い方が正しいので問題無いかと思います。エスケープシーケンスがややこしいだけです。
>関数内のカンマは第n引数と第n+1引数(nは1以上の自然数)を区切る以外の機能は持ち合わせていない
この点も仰る通りで、間違いないと思います。
13 commentaires
しん
le 13 Mar 2023
仰る通りで、「'''」→「'」ではなく「''」==「'」となります。
一重引用符が3つ並ぶ場合は、文字ベクトルを括る一重引用符と重なる場合です。
test = 'load('''; % 一重引用符が3つ並ぶ場合:最初の2つは文字ベクトルの一文字としての一重引用符、次の1つは文字ベクトルを括る一重引用符
disp(test)
しん
le 13 Mar 2023
Atsushi Ueno
le 13 Mar 2023
Modifié(e) : Atsushi Ueno
le 13 Mar 2023
>下記質問は上記を前提にさせて頂きますが、ここまでは認識間違っていないでしょうか?
一点大事な点として伝えたいのは「cmdに命令(文字ベクトル)として納められた load 関数が eval 関数で実行されるまでは、その中身は評価されない」という事です。従って、load 関数における引数の解釈は、エスケープシーケンスを取り除いてから検討しても良いのではないかと思います。
これならどうでしょうか?
first = 'load('''; disp(first) % disp()を使えば、実際の文字ベクトルだけが表示される
second = 'sample.mat'; disp(second)
third = ''','''; disp(third)
CheckList = {'check1','check2','check3'}; % テスト用
fourth = strjoin(rot90(CheckList,3),''','''); disp(fourth)
fifth = ''');'; disp(fifth)
cmd = [first, second, third, fourth, fifth]; disp(cmd)
Atsushi Ueno
le 13 Mar 2023
> 実際デバックすると繰り返しになり恐縮ですが、第1引数がBeforeName、第2引数がstrjoin(rot90(CheckList,3),''',''')となっており、この挙動自体が良く理解出来ません
私の書いた例だと最終的に第1引数が「sample.mat」、第2引数が「check1','check2','check3」となりました。(誤解を避ける為「」を使いました)。全て解釈された後の文字ベクトルは「load('sample.mat','check1','check2','check3');」で、これが実行したい命令文(の例)です。
>自分なりに考えましたが、当該挙動は下記の通り2つ考えられると思っています。
①一重引用符のみが関数の引数として指定された場合は引数として扱われない
⇒その様な事があるとすれば「’’」即ち空文字が渡されるケースが考えられます。一重引用符が単独で引数として渡される事はあり得ない(何らかのエラーが出る)と思います。
②一重引用符のみが関数の引数として指定された場合はカンマが機能しない。
⇒その様な事はありません。
>上記2つ以外の仕様もあるかも分かりませんが、それ以外の仕様としては「一重引用符」の箇所が「二重引用符」でも同様等と考えています。
⇒仰る通りです。
>ただ一番最初の質問にて下記の通り回答を頂いてますので、もしかすると②は仕様としてはないのではとも思っています。(関数内のカンマは第n引数と第n+1引数(nは1以上の自然数)を区切る以外の機能は持ち合わせていない⇒この点も仰る通りで、間違いないと思います)
⇒そうですね。関数の括弧内に書くカンマは引数を区切る機能なので、②の様な事はありません。
> ヘルプページのload関数の説明にて「load(filename,variables)」と記載されていますが、cmd = ['load(''',BeforeName,''',''',strjoin(rot90(CheckList,3),''','''),''');']というプログラムは上記のパターンとMATLABは理解するで間違っていませんでしょうか?
BeforeName = 'sample.mat';
CheckList = {'check1','check2','check3'}; % テスト用
cmd = ['load(''',BeforeName,''',''',strjoin(rot90(CheckList,3),''','''),''');']
filename ← 第1引数はBeforeName (='sample.mat') が対応します
variables ← 第2引数(以降)はstrjoin(rot90(CheckList,3),''',''') (='check1','check2','check3') が対応します
first = 'load('''; disp(first) ←第1引数はfilenameの為NG
→第1引数はload関数の仕様からfilenameしか指定できないと理解していますが合ってますでしょうか?
>第2引数は可変個数なので、第3引数、第4引数…と続く事が想定されます。
上記ご回答から第3引数以降の引数はご回答頂いた通り、仕様上問題無く動作すると理解しております。
が第2引数に関してはvariablesの所filenameを指定していまっているので動作しない。
second = 'sample.mat'; disp(second) ←第2引数はvariablesの為NG
third = ''','''; disp(third) ←第3引数以降はvariablesの為OK
fourth = strjoin(rot90(CheckList,3),''','''); disp(fourth) ←第3引数以降はvariablesの為OK
fifth = ''');'; disp(fifth) ←第3引数以降はvariablesの為OK
>プログラムの挙動自体はご教示頂いた通りで、自身も理解しておりその点に関しては異論は無いのですが、公式のヘルプページの記載が良く分からず確認しております。(実際のプログラムの挙動と相違がある為)恐れ入りますがその点に関して、以前のやり取りも含めご回答頂けますと幸いです。
下記は文字ベクトルを連結する為の構文であり、これ自身が文字ベクトルの中身を実行する訳ではありません。それを行うには eval 等のMATLAB式を評価する関数を実行する必要があります。下記に例を示します。
cmd = ['fprintf(''','today is hot.','\n','今日は暑いです。',''');']
eval(cmd); % 文字ベクトルcmdをコマンドとして実行する
first = 'load('''; disp(first) ←第1引数はfilenameの為NG
→第1引数はload関数の仕様からfilenameしか指定できないと理解していますが合ってますでしょうか?
⇒この流れの問答は私の勘違いがありました。まず他の意図で書かれたコメントをそのままコピペしてしまった事。そして、「load('」は load 関数本体を記述する為に書いた文字で第1引数ではないのに、私が変数名をfirstとした事で誤解を与えてしまったという事ですね。私は単に文字列を連結する際の変数名を1,2,3,4,5番目と表したかっただけです。下記の様に変数名を変更すれば、@しんさんの解釈に沿う表現になりますでしょうか?
func = 'load('''; disp(func) % disp()を使えば、実際の文字ベクトルだけが表示される
first = 'sample.mat'; disp(first)
dlmtr = ''','''; disp(dlmtr)
CheckList = {'check1','check2','check3'}; % テスト用
second = strjoin(rot90(CheckList,3),''','''); disp(second)
dlmtr2 = ''');'; disp(dlmtr2)
cmd = [func, first, dlmtr, second, dlmtr2]; disp(cmd)
Atsushi Ueno
le 14 Mar 2023
Modifié(e) : Atsushi Ueno
le 14 Mar 2023
>上記は例としてセミコロンになっていますが、私がそもそも質問していたプログラムではカンマになっています。
⇒それは無理もない話で、私が各要素を複数行に分けて書き下したので、出力を抑制する為にセミコロンで区切らざるを得なくなっています。
>上記の場合はそれで正しいのは分かりますが、そもそも下記の場合はカンマで引数を区切って指定していると思っていますが、下記の場合でも第1引数はBeforeNameになるのでしょうか?
⇒はい。load関数にとっての第1引数はBeforeName(当該変数の内容)です。
>カンマで区切られているので、下記の場合ですと引数は6個あると思っていますが、認識間違っていますでしょうか?(デバックするとそうならないので認識が違うのは自覚しておりますが、公式ヘルプページの記載から理解出来る説明をお願いします。)
⇒cmd = ['load(''',BeforeName,''',''',strjoin(rot90(CheckList,3),''','''),''');'] の図解です。これでどうでしょう。
なんかどうもデバッグに関する見解で認識違いが生じている様ですね。

しん
le 16 Mar 2023
Atsushi Ueno
le 16 Mar 2023
Modifié(e) : Atsushi Ueno
le 16 Mar 2023
>load関数の先頭にある一重引用符が消えるのは変数cmdに代入されることと関係ありますでしょうか?
いいえ関係ありません。私が無意識に一重引用符を書いたり書かなかったりしていました。理解を妨げる様な描き方になってしまい申し訳ありません。下記に統一して書く様に修正した図を添付します。

- 水色の枠外に書いた一重引用符が文字ベクトルである事を示す為に括った一重引用符です
- 水色の枠内に描いた一重引用符は、緑色の枠内と違ってエスケープシーケンスが除かれています。本来MATLABでこのような表現方法はできません。(それが無意識に消した理由です)
- 図の右側に文字ベクトルの連結を例として併記しました
これで下記3種類の一重引用符が混在している事が明確になったかと思います。
- エスケープシーケンスとしての一重引用符
- 文字そのものとしての一重引用符
- 文字ベクトルである事を示す一重引用符
Atsushi Ueno
le 16 Mar 2023
Catégories
En savoir plus sur Whos dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!