なでしこを明後日の方向に

日本語プログラム言語なでしこを応援しています

なでしこ3で関数を同期・非同期で実行する

nadesi.com

プログラム言語「なでしこ」のプログラムはプログラム貯蔵庫で実行できます

🍯 プログラム貯蔵庫

※ この記事はなでしこv3.8.7のころ書かれたものです

同期・非同期の違い

時間のかかる処理に対して、完了を待つか、完了を待たずに別の処理をするかという違いです

見たほうが早そうなのでプログラムの実行結果を見てもらいましょう

「関数から抜けました」「完了しました」の表示順が異なっています。

●テスト用関数:
 「開始します」と表示
 1秒待つ   //時間がかかる処理
 「完了しました」と表示

テスト用関数
「関数から抜けました」と表示

・実行結果
開始します
完了しました
関数から抜けました

これが同期をとっている関数呼び出しで、なでしこ3ではこの動作が標準となります。

●テスト用関数:
 「開始します」と表示
 1秒待つ   //時間がかかる処理
 「完了しました」と表示

{関数}テスト用関数を実行
「関数から抜けました」と表示

・実行結果
開始します
関数から抜けました
完了しました

これが非同期で実行した結果です。
時間のかかる処理を待ちつつ、関数からでて次の処理に移ります

文法について

{関数}テスト用関数の部分は関数を変数に変換する処理です。 変数にしたものは実行、JS関数実行、AWAIT実行の命令で実行できます。

AWAIT実行で実行すると同期を待つ、標準に近い動作になります。 実行、JS関数実行で実行すると、非同期での実行になります

命令群はマニュアルを参照

nadesi.com

使い分け

関数が「ファイルをダウンロード後に保存」「保存したファイルを解凍」といったものに分かれている場合は、保存の完了を待たないと解凍が失敗してしまいます。

関数が「ファイルをダウンロード後に保存」だけでよければ、保存の完了を待たずに次のファイルをダウンロードしはじめる「非同期実行」にすると早く作業が終わるでしょう。

なでしこ3で画像差分用のパーツ合成ツールを作成

nadesi.com

プログラム言語「なでしこ」のプログラムはプログラム貯蔵庫で実行できます

🍯 プログラム貯蔵庫

※ この記事はなでしこv3.7.24のころ書かれたものです

なでしこ3で「画像差分用のパーツ合成ツール」とかいうものを作って投稿してきました

n3s.nadesi.com

何をするツールか

ゲームによくある「表情差分」を2枚以上組み合わせて、別の画像をつくるためのものです

一度に3枚ロードして片目はこの差分から、口はこの差分から、みたいにつまみぐいが簡単にできます。

この絵の場合、上3枚がゲームから撮った絵で、左の絵をベースに片目と口のパーツをとってきたのが下の絵になります

ブラウザ内のみで画像処理するので外部にアップロードされることはないですし、サイズなどの制限もつけていません。 できあがった画像はpng形式でダウンロードできます

つかいかた

準備として、ゲームのスクリーンショットを撮ります。表情を変えて何枚か撮ります。 (最近のソシャゲは立ち絵がうにうに動くのですが、そういうのはムリです)

ツールを起動します。webアプリなのでURLに行くだけです。

画像をいくつか選択して、ブラウザにまとめてファイルドロップします。 最後の画像がキャンバスに表示されるはずです

マウスで画像ぽちぽちして頂点を追加します。2点のときは矩形、3点以上で多角形になります。
その内側が別の絵で上書きする範囲です

口を範囲指定したところ

どの絵で上書きするかは左の1.2.3みたいなやつで選びます。 この例だと、多角形の範囲を4番目の絵で上書きします

このように範囲と絵の番号を選択したら「確定」のボタンをクリックします。

頂点や確定のボタン類

頂点座標の手入力とか、元に戻す・やり直しボタンを設けてあります。

完成した画像はダウンロードできます。個人の範囲でお楽しみください。

プログラムで工夫した点

関数名を無駄に雅(みやび)にしました

//ユーザー様へ頂点データをさしあげる
●頂点献上

//ユーザー様から頂点データをいただく
●頂点賜る

//ユーザー様へ画像を納品する
●画像奉納

ユーザー様と直接かかわる関数名は敬語のレベルを上げました。 日本語として適切かどうかはわかりません。適当だね

なでしこ3でURLパラメータを取得する

今日のテーマ絵

ちがうよAIくん


nadesi.com

プログラム言語「なでしこ」のプログラムはプログラム貯蔵庫で実行できます

🍯 プログラム貯蔵庫

※ この記事はなでしこv3.7.21のころ書かれたものです

今回のテーマ

なでしこ3のブラウザ版(wnako)はブラウザ上で動作します。
変数にブラウザのURLパラメータを取得して入れることができるので、その方法を解説します。

というテーマでAIに記事のたたき台を書かせたらデタラメだったので自分で書きます

URLパラメータとは(AI生成文)

URLパラメータとは、WebページのURLの末尾に付けられる追加情報のことです。 例えば、次のようなURLがあります。

https://example.com/index.html?name=Taro&age=20

?以降の部分がパラメータで、name=Taro や age=20 のように キーと値の組み合わせ で構成されています。 Webアプリでは、ユーザーの入力や状態をURLパラメータで受け渡すことがよくあります。

表示しているページのURLを取得する

直接URLパラメータを取得する命令はなく、URLの文字列を取得してそれを変換することになります

URLの文字列は変数ブラウザURLに入っています

📖 なでしこ3 マニュアル - plugin_browser/ブラウザURL

WINDOW["location"]["href"]を参照することでも取得できます

どちらでもよい

URLの文字列をパラメータに変換する

URLの「?」以降の部分がパラメータなので自力で文字列処理をしてもよいのですが、変換する命令もあります。

URLパラメータ解析命令は「URLパラメータを解析してハッシュで返す」と説明にあります

📖 なでしこ3 マニュアル - plugin_system/URLパラメータ解析

まとめ

なでしこ3ではブラウザURLをURLパラメータ解析と書けば辞書型でパラメータを変数に入れることができます

わかってしまえば簡単なので記事は短くなりましたが、 なでしこ3の命令表では離れたところに書いてあるので調べるのに手間取りました。

なでしこの助詞は名前付き引数である

今日のテーマ絵


nadesi.com

プログラム言語「なでしこ」のプログラムはプログラム貯蔵庫で実行できます

🍯 プログラム貯蔵庫

※ この記事はなでしこv3.7.20のころ書かれたものです

なでしこの命令と引数と助詞の関係について

プログラミング言語「なでしこ」では命令の引数に助詞を付けます。 以下のプログラムでは命令置換は3つの引数をとりの, を, にが助詞にあたります

//なでしこ3
「こんにちは」の「にち」を「ばん」に置換 //→こんばんは
//(引数+助詞),(引数+助詞),(引数+助詞),命令 という構造

プログラム言語の名前付き引数の特徴を検索してみると

  • 可読性がよい
  • 引数の順序を入れ替えてもよい

といったことが挙げられます。

なでしこ3の助詞は同様の特徴を持っており、助詞はほかのプログラム言語でいう名前付き引数(キーワード引数)にあたる と言ってよいと思います

なでしこ3の助詞一覧

なでしこ3で使用できる文法上の助詞は以下のものであると定義されています
※ なでしこv3.7.20時点

について,くらい,なのか,までを,までの,による,として,とは,から,まで,
だけ,より,ほど,など,いて,えて,きて,けて,して,って,にて,みて,
めて,ねて,では,には,んで,ずつ,
は,を,に,へ,で,と,が,の,でなければ,なければ,ならば,なら,たら,れば,
こと,である,です,します,でした,にゃん

用途はいくつかのグループにわかれています

  • 関数の引数につかうもの(を, に, へ, で, と, が, の, から, まで, にはなど)
  • 文法的な意味を持つもの(は, には, して, ならば, でなければなど)
  • 意味はなくプログラム文のかざりになるもの(です, でした, にゃんなど)

これ助詞だっけ?と感じるものもあるかもしれませんが、日本語の助詞には格助詞・接続助詞・終助詞などが含まれるにゃん(←終助詞)

(余談)読点の省略

なでしこ以外のプログラム言語に慣れていて、なでしこのプログラム文が不思議に感じる方は助詞の後ろに読点をつけてみるとよいでしょう。

「こんにちは」の、「にち」を、「ばん」に、置換

「、」は文法上の区切り位置になります。ほかの言語でいう、.や, や (半角スペース)と同様です

なでしこの前身である「日本語プログラミング言語ひまわり」では読点が必須でしたが、なでしこでは助詞につける読点が省略可能になりました。(省略せずに「、」を書いても動きます)

もしかしたら、この省略によって単語の区切り位置が一見分かりにくい不思議な言語に見られるようになっってしまったのかもしれません。

なでしこの文法に慣れている人は 助詞が区切り位置に見えています。

なでしこv1付属のエディタ

というのも、なでしこv1に付属してるエディタでは助詞にしっかり色がつくのです(画像はダークモード)

ほかのプログラム言語との比較

関数に引数を渡す様子をほかのプログラム言語と比較してみます

名前付き引数なしの場合

引数は順番で役割が固定されるプログラム言語では置換(S, A, B)のようになります。 何番目の引数が何の役割か、不安を覚えます。 引数が増えると地獄です。

名前付き引数ありの別言語の場合

プログラム言語によっては 名前付き引数 が導入されています

Range("A1:A100").Replace What:="にち", Replacement:="ばん"`

VBAでは What:=やReplacement:=が引数を指定している部分です。

AIにパイソンで書いたらどうなるのと聞いたところ、こう返ってきました

def replace_all(*, text, old, new):
    return text.replace(old, new)

result = replace_all(text="こんにちは", old="にち", new="ばん")
print(result)   # → こんばんは

標準の関数は名前付き引数がついていないため、関数定義で実装するようです。 text=、old=、new=が引数を指定している部分のようです。

比較

これまでの例をならべて見ましょう

//C言語ほか
置換(S, A, B)

' VBA
Range("A1:A1").Replace What:="にち", Replacement:="ばん"

# Python
replace_all(text="こんにちは", old="にち", new="ばん")

※ なでしこ
「こんにちは」の「にち」を「ばん」に置換

なでしことパイソンを比較すると画像のようになります。

対応する部分

おまけ:AIに聞いてみた

プログラム言語ではなく通常の英語で「SのAをBに置換する」はどのように書きますかと尋ねたところ

Replace A with B in S.

と返ってきました。 これがそのまま動くプログラム言語はありますかって聞いたらAppleScriptとCOBOLが近いと返ってきました

・AppleScript
set newText to replace "A" with "B" in S

・COBOL
INSPECT S REPLACING ALL A BY B.

前置詞by, to, with, inなどをなでしこの助詞みたいにすればよかったんじゃないの? 英語圏民はなんでこれ発展させていかなかったの?

なでしこの新プロパティ構文(助詞+$)を試してみる

今日のテーマ


nadesi.com

プログラム言語「なでしこ」のプログラムは貯蔵庫エディタで実行できます

🍯 プログラム貯蔵庫


なでしこv3.7.20がでました

なでしこのv3.7.20(2026/05/21)で以下の更新がありました

プロパティ構文「$」前の助詞/配列アクセス「@」前の助詞を記述可能に。

これの記述方法について解説していきます

記号「$」について

なでしこ3の初期の記述方法では、ラベルの部品に色を付けるにはこう書いていました

//なでしこ3
「あいうえお」のラベル作成
それの「背景色」に水色をDOM属性設定

少し時が経ち、ラベルなどのオブジェクトに$や.でアクセスできるようになりました

//なでしこ3
「あいうえお」のラベル作成
それ$背景色は水色 
それ.背景色は水色 //$と.は同じ意味

オブジェクト.プロパティの形は別のプログラム言語でよくでてきます。 短く書けるので便利になりました。

でもなでしこで.や$の記号を連発すると日本語プログラム言語として読みにくい姿になっていくんですよね
記号がはさまると音読(黙読)がしにくいのが原因だと思っています

声に出して読んでみよう

新しい記法の場合

新しい記法では$の前に助詞をつけてもよいルールになりました

プロパティ構文「$」前の助詞/配列アクセス「@」前の助詞を記述可能に。

つまりこう書けます

「あいうえお」のラベル作成
//それ$背景色は水色 //以前の書き方
それの$背景色は水色 //動作は同じ

$の前に助詞のをつけることができます。 メリットは音読がしやすくなることで、デメリットはタイピング量が1文字増えることです

デメリットを消す仕様!

タイピング量が1文字増えることがデメリットと言いましたが、実は1文字減らすことができる仕様があります

変数そです

システム側に変数名そが定義されており、DOM部品作成したときに値が入ります

内部実装

ラベル作成やボタン作成などの部品作成命令はこの関数を通ります。そのときそに作成された部品が入ります。よって以下のように書けます。

「あいうえお」のラベル作成
その$背景色は水色

それがそになることで1文字減らすことができ、読みやすさも維持しています

なお内部では助詞や記号で文字区切りが行われるので そ | の$ | 背景色 | は | 水色 のように区切られているはずです

変数名がそであるのは、プログラム内でそのって書きたいから、というわけです

なでしこ3でイベント委譲のプログラムをつくってみよう

nadesi.com なでしこ3のプログラムは貯蔵庫エディタで実行できます n3s.nadesi.com

※ この記事はなでしこ3.7.17のころ書かれたものです

ブラウザ版のなでしこ3で イベント委譲 を利用したプログラムを作ってみましょう。 まずはサンプルから!

サンプル

親となるラベル1つと、子となるボタン3つを作ります。 ラベルにはクリック時のイベントを書きます

//なでしこ3
親=「」のラベル作成
3回:
 「ぼたん{回数}」のボタン作成
 それを親にDOM子要素追加

親のクリックした時には:
  対象からテキスト取得
  それを言う

部品を親子関係にするにはDOM子要素追加を使います

親のラベル部品にはクリックした時のイベントをつけています。 子のボタン部品にはクリックした時のイベントをつけていませんが、クリックすると イベントが起きます

これは イベント委譲 によるものです。この場合、ぼたん3をクリックすると「ぼたん3」のダイアログがでます

そして この先の文章はAI生成です(暴露)
ただし長すぎたし変なところがあったので直したりカットしたりしました。

AI生成ここから

イベント委譲とは

イベント委譲とは、

子要素に発生したイベントを、親要素がまとめて受け取るテクニック

のことです。

JavaScriptではよく使われる方法で、なでしこ3のDOM部品でも考え方が使えます。

今回の例では、ボタンを3つ作っています。

もしイベント委譲を使わない場合は、

  • ボタン1にクリックイベントを付ける
  • ボタン2にクリックイベントを付ける
  • ボタン3にクリックイベントを付ける

…と、3回イベント設定をしなければいけません。

しかし、イベント委譲を使えば、 親に1つイベントを付けるだけで、すべての子ボタンのクリックを拾える というメリットがあります。

どうして親が子のイベントを拾えるの?

ブラウザのイベントには「バブリング(伝播)」という仕組みがあります。

  1. 子要素でイベントが発生する
  2. そのイベントが親 → さらに親へと伝わっていく

この伝わる途中で、親が「お、イベント来たな」と拾うことができるわけです。

今回のコードのこの部分がまさにそれです。

親のクリックした時には:
  対象からテキスト取得
  それを言う

「対象」とは、実際にクリックされた要素(=ボタン)です。 親はクリックイベントを受け取ったときに「どの子がクリックされたのか」を知ることができます。

実際の動作の流れ

ここで、今回のサンプルが内部でどう動いているかを整理してみましょう。

  1. 親要素を作る(ラベル作成)
  2. 3つのボタンを作り、それぞれ親にDOM子要素追加する
  3. 親に「クリックした時」イベントを設定する

ここでクリック待ちになります。

  1. ボタンがクリックされる
  2. クリックイベントが親へ伝わる(バブリング)
  3. 親のクリックした時が動く
  4. 対象(=クリックされたボタン)のテキストを取得
  5. そのテキストを「言う」

つまり、ボタン自身は何も知らないのに、親が全部面倒を見てくれているという構造です。

イベント委譲のメリットまとめ

  • 子要素が増えてもイベント設定は1回で済む
  • 動的に追加された要素にも自動で対応できる
  • コードがスッキリする
  • パフォーマンスが良くなる(大量の要素にイベントを付けなくて済む)

特に「後からDOMを追加する」ケースでは、イベント委譲は非常に強力です。

AI生成ここまで

今回はサンプルプログラム1個つくって、AIにテーマを伝えて「続きを書いてください」で生成してみました。 ちなみに検索サイトで「ブログ記事」と入れるとサジェストに「aiで書く」がありました。

まとめ

  • 部品を親子にして、親部品にだけイベントをつける手法があるよ!
  • 親の部品は「」のラベル作成みたいなラベルがいいよ!
  • 部品を親子関係にするにはDOM子要素追加を使うよ!

なでしこ3の検索命令で失敗した場合の返り値

nadesi.com

※ この記事が書かれたのはなでしこv3.7.16 時点です

なでしこには文字検索や範囲切り取るなど文字を探して何かを返す命令がたくさんあります。
マニュアルには見つかったら何を返すか書いてあるけど、 見つからなかったらどうなるか 書いてなかったりします。

なので試してみました

前知識として、なでしこ3のシステム定数をいくつか紹介します。 javascriptの用語と対応しています

なでしこの定数 説明
空 javascriptの空文字列""のこと
未定義 javascriptのundefinedのこと
無限大 javascriptのInfinityのこと(数値としてふるまう)
NULL javascriptのnullのこと

文字列処理の命令

・試したこと 文字列Sから何かを探す命令には、ヒットしない場合(見つからなかった)は何を返すか・どんな動作をするか、など
文字数とりだす関連の命令にはでかい数(無限大)を与えたときの挙動など

●SでAが何文字目

通常:Aの文字位置を戻す(最初の文字は1文字目)
 Aがヒットしない場合、 0を戻す

●SのpからAを文字検索

通常:位置pより後ろのAの文字位置を戻す(最初の文字は1文字目)
 Aがヒットしない場合、 0を戻す

●SをAで区切る

通常:SをAで分割した配列を戻す
 Aがヒットしない場合、要素数1の 配列[S]を戻す
 Sを空で区切るとした場合、 文字列分解の動作になる

●SをAで文字列分割

通常:要素数2の配列 [Aの手前,Aの後ろ] を戻す
 Aがヒットしない場合、要素数1の 配列[S]を戻す
 Sを空で文字列分割とした場合、要素数2の配列["",S]を戻す

●SのAまで切取る

通常:文字列Aの手前までの文字列を戻す。Aの後ろを対象に入れる
 Aがヒットしない場合、 末尾まで切り取る。
 Sを空まで切取るとした場合、空を戻す。対象にSが入る

●SのAからBの範囲切取る

通常:AからBの間の文字を戻す。
 Aがヒットしない場合、 空を戻す。切り取らない。
 Aがヒットし、 Bだけがヒットしない場合、末尾まで切り取る

●SのAからCNTを文字抜出

  通常:A文字目からCNTの文字数だけ取り出して返す
 AがSの文字数より大きいと空を返す
 CNTがマイナスだと空を返す
 CNTに 無限大を指定するとA文字目から後ろの文字すべてを返す
(例)「いろはにほへと」の3から 無限大 を文字抜出す //→はにほへと

●SがAに正規表現マッチ

通常:Aを「/」で囲うかどうかで挙動が変わる。「/A/」の場合、文字列を返す。違えば配列を返す
 Aがヒットしない場合、 NULLを戻す
 NULLとの比較はミスしがちなので、もしSがAに正規表現マッチするならばと書くのが無難。  

●SをAで正規表現区切る

 Aがヒットしない場合、要素数1の 配列[S] を戻す
 Sを空で正規表現区切るとした場合、文字列分解の動作になる

配列関連の命令

・ためしたこと
マイナスの値を入れたり、大きいマイナス値を入れたり、無限大を入れたりした

●ARからAを配列検索

通常:0以上の値を返す
 Aにヒットする要素がない場合、 -1 を戻す

●ARからNを配列切取

通常:N番目の要素をひっこぬいて返す。ARを変更する。
 Nに マイナスを指定すると配列の後ろから数える (-2ならうしろから2番目)
 要素数より 大きいマイナス値を指定すると0番目が切り取られる
 要素数より大きいNを指定すると、未定義(undefined)を戻す。ARは変化しない。

●ARのNからCNTを配列取出

通常:N番目の要素からCNT個だけひっこぬいて返す。ARを変更する。
 Nに マイナスを指定すると配列の後ろから数える (-2ならうしろから2番目)
 Nに大きいマイナス値を指定すると0番目から切り取られる
 Nに大きいNを指定すると、空の配列 [ ]を戻す
 CNTに 大きいNを指定すると、Nから後ろすべて取り出す
(例)ARの3から無限大を配列取り出すと書くと配列の3番目から後ろすべてを取り出す

●ARのNを配列参照

通常:配列のN番目の値を返す。範囲オブジェクトを指定すると配列からその範囲をコピーしたものを返す
 Nに マイナスを指定すると未定義(undefined)を返す。※
 Nに要素数より大きいNを指定すると、未定義(undefined)を返す。
 Nに 範囲オブジェクトを指定した場合、マイナスを指定すると配列の後ろから数える (-2ならうしろから2番目)
 Nに範囲オブジェクトを指定した場合、大きい開始地点を指定すると、空の配列 [ ]を戻す
※ これはのちのバージョンで変わるかも?

●ARのIとJを配列入替

通常:配列のI番目とJ番目を入れ替える
 Iに マイナスを指定すると、AR[J]は未定義(undefined)になる
 Iに要素数より大きい値を指定すると、AR[J]は未定義(undefined)になり、AR[I]=AR[J]は行われる
 IとJを逆にしても同様
 大きい値で入れ替えると要素数が拡張される(下図)

おわりに

検索命令は文字列の場合は0、配列の場合は-1が返るようです

正規表現マッチだけはNULLが返ってくるので、分岐する場合はもしSがAに正規表現マッチするならばと書いてしまうのが無難。

「いろはにほへと」の3から無限大を文字抜出すやARの3から無限大を配列取り出すで特定位置からうしろすべてを取りだせるので、これは便利に使えそう