0Pricing
Lua Academy · レッスン

クロージャ間で共有されるUpvalue

複数のクロージャで同じupvalueを共有する方法と、変更による影響を学びます。

「クロージャ間で共有されるUpvalue」はCoddyKit上の無料Lua Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLua Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Lua Academyコースには全4レッスンが含まれています。

同じUpvalueの共有

同じスコープで定義された2つのクロージャは、まったく同じUpvalueセルを共有できます。一方による変更は、もう一方からも確認できます。

local function makeGetterSetter()
  local value = 0
  local function get() return value end
  local function set(v) value = v end
  return get, set
end
local get, set = makeGetterSetter()
set(42)
print(get())  -- 42

共有が発生する理由

LuaはクロージャごとにUpvalueをコピーしません。同じブロック内で作成され、同じローカル変数を参照するすべてのクロージャは、1つのUpvalueセルを共有します。

共有UpvalueによるObserver Pattern

共有Upvalueは、複数のクロージャ間のメッセージバスとして機能します。

local count = 0
local inc = function() count = count + 1 end
local dec = function() count = count - 1 end
local get = function() return count end
inc(); inc(); dec()
print(get())  -- 1

ループ変数に関する注意点

numeric forループでは、反復ごとに新しいローカルなループ変数が作成されるため、クロージャはそれぞれ独立したUpvalueをキャプチャします。

local fns = {}
for i = 1, 3 do
  fns[i] = function() return i end
end
print(fns[1](), fns[2](), fns[3]())  -- 1 2 3 (each closure has its own i)

whileループのループ変数に関する注意点

whileループで変化する1つの変数をクロージャで参照すると、すべてのクロージャが同じUpvalueを共有し、最後の値を確認することになります。

local fns = {}
local i = 0
while i < 3 do
  i = i + 1
  fns[i] = function() return i end  -- all share same i!
end
print(fns[1]())  -- 3 (not 1!)

新しいローカル変数のキャプチャ

whileループで独立した値をキャプチャするには、ループ本体の中で新しいローカル変数を導入します。

local fns = {}
local i = 0
while i < 3 do
  i = i + 1
  local ci = i  -- new local per iteration
  fns[i] = function() return ci end
end
print(fns[1]())  -- 1, fns[2]() == 2

共有状態モジュールパターン

モジュールは、Upvalueを通じてプライベートな状態テーブルを共有する複数の関数を公開できます。

local function makeStack()
  local data = {}
  return {
    push = function(v) data[#data+1] = v end,
    pop  = function() local v = data[#data]; data[#data]=nil; return v end,
    size = function() return #data end,
  }
end

エイリアスと変更

注意してください。同じUpvalueを参照するすべてのクロージャは、同じ変更を即座に確認します。これは強力な仕組みですが、意図しない結合を引き起こすことがあります。

Upvalueの同一性

debug.upvalueid(f, n)は、関数fのn番目のUpvalueの一意な識別子を返します。同じUpvalue IDを持つ2つのクロージャは、同じセルを共有します。

debug.upvaluejoin

debug.upvaluejoin(f1, n1, f2, n2)を使うと、f1のn1番目のUpvalueが、f2のn2番目のUpvalueと同じセルを共有するようになります。デバッグ用の低レベルなツールです。

実践的なパターン

  • プライベート変数を共有するGetter/Setterの組み合わせ
  • 複数のクロージャからリセット機能を公開するイベントカウンター
  • 複数のAPI関数で共有するモジュール状態

共有Upvalueに関する質問

同じスコープでgetとsetという2つのクロージャを作成し、どちらもvalueをキャプチャしています。set(99)を呼び出すと、get()は何を返しますか?

まとめ:共有Upvalue

同じスコープにあるクロージャは、Upvalueセルを共有します。変更は、共有しているすべてのクロージャから即座に確認できます。これは、Luaにおけるカプセル化とモジュール状態の基盤です。

よくある質問

「クロージャ間で共有されるUpvalue」レッスンは無料ですか?

はい。「クロージャ間で共有されるUpvalue」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Lua Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Lua Academyコースには全4レッスンが含まれています。

「クロージャ間で共有されるUpvalue」で何を学びますか?

複数のクロージャで同じupvalueを共有する方法と、変更による影響を学びます。 ブラウザで直接実行するハンズオンコードでLua Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Lua Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのLua Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「クロージャ間で共有されるUpvalue」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このLua Academyレッスンでコードを書いて実行できますか?

はい。すべてのLua Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Upvalueとは
  2. クロージャ間で共有されるUpvalue
  3. ファクトリー関数とジェネレーター
  4. クロージャによるメモ化
← Lua Academyに戻る