2016-11-03 13 views
1

AutomagicTables(http://lua-users.org/wiki/AutomagicTables)を使ってLuaメタテーブルのヘルプが必要です。定義されていないテーブルに割り当てる機能は非常に便利です。この機能を維持したいと思います。私のバージョンは、単一の関数に配置されています:デフォルトと自動テーブル作成を伴うLuaテーブル

require("dataentry") -- Contains my age function 
function AutomagicTable() 
-- Create a new data table 
-- from https://lua-users.org/wiki/AutomagicTables 
    local auto, assign 

    function auto(tab, key) 
    return setmetatable({}, { 
     __index = auto, 
     __newindex = assign, 
     parent = tab, 
     key = key 
    }) 
    end 

    local meta = {__index = auto} 

    function assign(tab, key, val) 
    if val ~= nil then 
     local oldmt = getmetatable(tab) 
     oldmt.parent[oldmt.key] = tab 
     setmetatable(tab, meta) 
     tab[key] = val 
    else 
     return nil 
    end 
    end 

    return setmetatable({}, meta) 
end 

は、私が欲しいのは、フィールドが定義されていないときに使用するデフォルトのテーブルを渡すことです - PIL第13章(https://www.lua.org/pil/13.4.3.html)で説明したように。これは私のデータstrucutreの計算フィールドとルックアップフィールドを許可します。 nilのテーブル[「DOB」]として失敗し、このコードの年齢()に

t_defaults = { 
    Age = age(table["DOB"]), 
    Sex = "Female", 
} 

t = AutomagicTable(t_defaults) 

t.ID12345.DOB = "7/2/1965" 
t.ID12346.DOB = "1/2/1945" 

print("ID12345",t.ID12345.Sex,t.ID12345.DOB,t.ID12345.Age) 
print("ID12346",t.ID12346.Sex,t.ID12346.DOB,t.ID12346.Age) 

注現在のテーブルのDOBフィールドへの参照(下記参照):以下は、私が使用したい構文です。このコードをデフォルト値がないところで実行すると、Automagicは欠損値のテーブルを返します。

私はPIL、第13章の例で、次のデフォルト値を割り当てることができますが、構文は厄介で、一度(私は別のメタテーブルを割り当てたとして)私はAutomagicTable機能を失う適用:「

-- Make a metatables 
t_defaults = {} 
t_defaults.__index = function (table, key) 
local def = { 
    Age = age(table["DOB"]), 
    Sex = "Female" 
    } 
return def[key] 
end 

-- Set new metatable - but now we can't make anymore Automagic tables 
setmetatable(t.ID12345, t_defaults) 
setmetatable(t.ID12346, t_defaults) 

-- This will work 
print("ID12345",t.ID12345.Sex,t.ID12345.DOB,t.ID12345.Age) 
print("ID12346",t.ID12346.Sex,t.ID12346.DOB,t.ID12346.Age) 

-- This assignment fails 
t.ID12347.DOB = "12/12/1945" 

残念ながら、私はドンAutomagicTablesコードを完全に理解し、AutomagicTableコード内に必要な機能を追加するのに苦労しています。

喜んでお寄せいただきありがとうございます。

ギャビン

答えて

0

ここでは、完全なオートマチックは必要ありません。
ユーザー(深度レベル1のオブジェクト)のみを自動的に作成する必要があります。
だから、もっとシンプルなロジックを使用することができる:

local function age(DOB_str) 
    local m, d, y = (DOB_str or ""):match"^(%d+)/(%d+)/(%d+)$" 
    if m then 
     local t = {month = tonumber(m), day = tonumber(d), year = tonumber(y)} 
     local now = os.date"*t" 
     local now_year = now.year 
     now = os.time{year = now_year, month = now.month, day = now.day} 
     local lower_bound = math.max(0, now_year - t.year - 1) 
     local completed_years = -1 + lower_bound 
     t.year = t.year + lower_bound 
     repeat 
     completed_years = completed_years + 1 
     t.year = t.year + 1 
     until os.difftime(now, os.time(t)) < 0 
     return completed_years 
    end 
end 

-- Class "User" 
local user_default_fields = {Sex = "Female"} 
local user_mt = {__index = 
    function (tab, key) 
     if key == "Age" then -- this field is calculatable 
     return age(tab.DOB) 
     else     -- other fields are constants 
     return user_default_fields[key] 
     end 
    end 
} 

-- The table containing all users with auto-creation 
local users = setmetatable({}, {__index = 
    function (tab, key) 
     local new_user = setmetatable({}, user_mt) 
     tab[key] = new_user 
     return new_user 
    end 
}) 


-- usage 
users.ID12345.DOB = "12/31/1965" 
users.ID12346.DOB = "1/2/1945" 

print("ID12345", users.ID12345.Sex, users.ID12345.DOB, users.ID12345.Age) 
print("ID12346", users.ID12346.Sex, users.ID12346.DOB, users.ID12346.Age) 
+0

感謝を。あなたの単一レベルのオートマチックははるかに理解しやすいです。 G – Gavin

関連する問題