本地函数可以在Lua中替换\ override本身

时间:2015-11-04 00:58:19

标签: function lua

在Lua中是否可以从内部替换本地函数?例如:

11-03 19:42:50.189  31488-31488/com.ibm.bluelist E/Zygote﹕ MountEmulatedStorage()
11-03 19:42:50.189  31488-31488/com.ibm.bluelist E/Zygote﹕ v2
11-03 19:42:50.189  31488-31488/com.ibm.bluelist I/libpersona﹕ KNOX_SDCARD checking this for 10086
11-03 19:42:50.189  31488-31488/com.ibm.bluelist I/libpersona﹕ KNOX_SDCARD not a persona
11-03 19:42:50.209  31488-31488/com.ibm.bluelist I/SELinux﹕ Function: selinux_compare_spd_ram, SPD-policy is existed. and_ver=SEPF_SM-G900M_5.0 ver=27
11-03 19:42:50.209  31488-31488/com.ibm.bluelist I/SELinux﹕ Function: selinux_compare_spd_ram , priority [1] , priority version is VE=SEPF_SM-G900M_5.0_0027
11-03 19:42:50.209  31488-31488/com.ibm.bluelist E/SELinux﹕ [DEBUG] get_category: variable seinfo: default sensitivity: NULL, cateogry: NULL
11-03 19:42:50.209  31488-31488/com.ibm.bluelist I/art﹕ Late-enabling -Xcheck:jni
11-03 19:42:50.259  31488-31488/com.ibm.bluelist D/TimaKeyStoreProvider﹕ TimaSignature is unavailable
11-03 19:42:50.259  31488-31488/com.ibm.bluelist D/ActivityThread﹕ Added TimaKeyStore provider
11-03 19:42:50.379  31488-31488/com.ibm.bluelist D/ResourcesManager﹕ creating new AssetManager and set to /data/app/com.ibm.bluelist-2/base.apk
11-03 19:42:50.519  31488-31488/com.ibm.bluelist I/BlueListApplication﹕ Found configuration file: bluelist.properties
11-03 19:42:50.519  31488-31488/com.ibm.bluelist I/BlueListApplication﹕ Application ID is: 58cf6be4-9e6f-4f10-910c-178ebed2883a
11-03 19:42:50.889  31488-31488/com.ibm.bluelist I/com.ibm.mobile.services.core.IBMBluemix﹕ IBMBluemix SDK initialization successful.
    IBMBluemix SDK Version: 1.0.1.20150311-1224
    BlueMix Target: https://winmobile.mybluemix.net
    applicationId: 58cf6be4-9e6f-4f10-910c-178ebed2883a
11-03 19:42:51.319  31488-31488/com.ibm.bluelist I/com.ibm.mobile.services.data.IBMData﹕ IBMData SDK initialization successful.
    IBMData SDK Version: 1.0.0.20150311-1224
11-03 19:42:51.389  31488-31527/com.ibm.bluelist I/System.out﹕ (HTTPLog)-Static: SBServiceAPI: getService class android.os.ServiceManager
11-03 19:42:51.389  31488-31527/com.ibm.bluelist I/System.out﹕ (HTTPLog)-Static: isShipBuild true
11-03 19:42:51.389  31488-31527/com.ibm.bluelist I/System.out﹕ (HTTPLog)-Thread-34254-140709693: SmartBonding Enabling is true, SHIP_BUILD is true, log to file is false, DBG is false
11-03 19:42:51.499  31488-31488/com.ibm.bluelist I/com.ibm.mobile.services.push.IBMPush﹕ IBMPush SDK initialization successful.
    IBMPush SDK Version: 1.0.0.20150311-1224
11-03 19:42:51.589  31488-31488/com.ibm.bluelist I/com.ibm.mobile.services.push.IBMPush﹕ IBMPushInvoker : Sending request to the Push server. Method : GET Request URL : https://winmobile.mybluemix.net/push/v1/apps/58cf6be4-9e6f-4f10-910c-178ebed2883a/settings/current
11-03 19:42:51.649  31488-31488/com.ibm.bluelist D/BlueListApplication﹕ Activity created: MainActivity
11-03 19:42:51.679  31488-31488/com.ibm.bluelist V/BitmapFactory﹕ DecodeImagePath(decodeResourceStream3) : res/drawable-xxhdpi-v4/ic_ab_back_holo_dark_am.png
11-03 19:42:51.739  31488-31488/com.ibm.bluelist V/BitmapFactory﹕ DecodeImagePath(decodeResourceStream3) : res/drawable-xxhdpi-v4/sym_def_app_icon.png
11-03 19:42:51.749  31488-31488/com.ibm.bluelist V/BitmapFactory﹕ DecodeImagePath(decodeResourceStream3) : res/drawable-mdpi-v4/plusbutton.png
11-03 19:42:51.769  31488-31488/com.ibm.bluelist D/AbsListView﹕ Get MotionRecognitionManager
11-03 19:42:51.779  31488-31488/com.ibm.bluelist V/BitmapFactory﹕ DecodeImagePath(decodeResourceStream3) : res/drawable-mdpi-v4/logo.png
11-03 19:42:51.789  31488-31488/com.ibm.bluelist D/Activity﹕ performCreate Call secproduct feature valuefalse
11-03 19:42:51.789  31488-31488/com.ibm.bluelist D/Activity﹕ performCreate Call debug elastic valuetrue
11-03 19:42:51.789  31488-31488/com.ibm.bluelist D/BlueListApplication﹕ Activity started: MainActivity
11-03 19:42:51.789  31488-31488/com.ibm.bluelist D/BlueListApplication﹕ Activity resumed: MainActivity
11-03 19:42:51.869  31488-31535/com.ibm.bluelist D/OpenGLRenderer﹕ Render dirty regions requested: true
11-03 19:42:51.979  31488-31535/com.ibm.bluelist I/Adreno-EGL﹕ <qeglDrvAPI_eglInitialize:410>: EGL 1.4 QUALCOMM build:  ()
    OpenGL ES Shader Compiler Version: E031.25.01.03
    Build Date: 03/03/15 Tue
    Local Branch: LA.BF.1.1_RB1_20150108_025_1077123_1158499
    Remote Branch:
    Local Patches:
    Reconstruct Branch:
11-03 19:42:51.989  31488-31535/com.ibm.bluelist I/OpenGLRenderer﹕ Initialized EGL, version 1.4
11-03 19:42:52.009  31488-31535/com.ibm.bluelist I/OpenGLRenderer﹕ HWUI protection enabled for context ,  &this =0xafcfe718 ,&mEglDisplay = 1 , &mEglConfig = 8
11-03 19:42:52.009  31488-31535/com.ibm.bluelist D/OpenGLRenderer﹕ Enabling debug mode 0
11-03 19:42:52.309  31488-31488/com.ibm.bluelist I/Timeline﹕ Timeline: Activity_idle id: android.os.BinderProxy@133d7119 time:123916211
11-03 19:42:52.469  31488-31527/com.ibm.bluelist E/com.ibm.mobile.services.core.http.IBMMutableHttpRequest﹕ Request to 'https://winmobile.mybluemix.net/data/helo' failed. IBMBLUEMIX-0300E: Request by com.ibm.mobile.services.data.IBMData was rejected by MAS.  Status=401, Response={"error":"You are not authorized.","status":"failure"}
    .
11-03 19:42:52.479  31488-31508/com.ibm.bluelist E/getToken(34252)﹕ Server rejected request for with status code 401
    com.ibm.mobile.services.data.internal.HttpFailure: Http Response Code: 401
            at com.ibm.mobile.services.data.internal.Connection.getToken(Connection.java:199)
            at com.ibm.mobile.services.data.internal.Connection.access$400(Connection.java:43)
            at com.ibm.mobile.services.data.internal.Connection$Receiver.run(Connection.java:412)
11-03 19:42:52.479  31488-31508/com.ibm.bluelist E/Connection:Receiver(34252)﹕ Http Response Code: 401
    com.ibm.mobile.services.data.internal.HttpFailure: Http Response Code: 401
            at com.ibm.mobile.services.data.internal.Connection.getToken(Connection.java:199)
            at com.ibm.mobile.services.data.internal.Connection.access$400(Connection.java:43)
            at com.ibm.mobile.services.data.internal.Connection$Receiver.run(Connection.java:412)
11-03 19:42:52.599  31488-31532/com.ibm.bluelist E/com.ibm.mobile.services.core.http.IBMMutableHttpRequest﹕ Request to 'https://winmobile.mybluemix.net/push/v1/apps/58cf6be4-9e6f-4f10-910c-178ebed2883a/settings/current' failed. IBMBLUEMIX-0300E: Request by com.ibm.mobile.services.push.IBMPush was rejected by MAS.  Status=401, Response=Error 401: {
    &quot;error&quot;: &quot;MASS016E: Invalid application secret is detected.&quot;
    }
    .
11-03 19:42:52.599  31488-31532/com.ibm.bluelist I/com.ibm.mobile.services.push.IBMPush﹕ IBMPushInvoker : Received response for GET https://winmobile.mybluemix.net/push/v1/apps/58cf6be4-9e6f-4f10-910c-178ebed2883a/settings/current : Response = 401 Unauthorized
11-03 19:42:52.649  31488-31532/com.ibm.bluelist E/com.ibm.mobile.services.push.IBMPush﹕ Error while retrieving GCM SenderId from server: Status Code : 401, Status Line : Unauthorized
11-03 19:42:52.659  31488-31581/com.ibm.bluelist E/com.ibm.mobile.services.push.IBMPush﹕ Registration failed Status Code : 401, Status Line : Unauthorized
11-03 19:42:52.669  31488-31581/com.ibm.bluelist E/BlueListApplication﹕ Exception : Status Code : 401, Status Line : Unauthorized
11-03 19:42:52.959  31488-31572/com.ibm.bluelist E/com.ibm.mobile.services.core.http.IBMMutableHttpRequest﹕ Request to 'https://winmobile.mybluemix.net/data/helo' failed. IBMBLUEMIX-0300E: Request by com.ibm.mobile.services.data.IBMData was rejected by MAS.  Status=401, Response={"error":"You are not authorized.","status":"failure"}
    .
11-03 19:42:52.969  31488-31509/com.ibm.bluelist E/getToken(34253)﹕ Server rejected request for with status code 401
    com.ibm.mobile.services.data.internal.HttpFailure: Http Response Code: 401
            at com.ibm.mobile.services.data.internal.Connection.getToken(Connection.java:199)
            at com.ibm.mobile.services.data.internal.Connection.access$400(Connection.java:43)
            at com.ibm.mobile.services.data.internal.Connection$Sender.run(Connection.java:516)
11-03 19:42:52.969  31488-31509/com.ibm.bluelist W/Connection:Sender(34253)﹕ com.ibm.mobile.services.data.internal.HttpFailure: Http Response Code: 401
            at com.ibm.mobile.services.data.internal.Connection.getToken(Connection.java:199)
            at com.ibm.mobile.services.data.internal.Connection.access$400(Connection.java:43)
            at com.ibm.mobile.services.data.internal.Connection$Sender.run(Connection.java:516)
11-03 19:42:52.969  31488-31488/com.ibm.bluelist E/MainActivity﹕ Exception : Http Response Code: 401
11-03 19:42:53.539  31488-31527/com.ibm.bluelist E/com.ibm.mobile.services.core.http.IBMMutableHttpRequest﹕ Request to 'https://winmobile.mybluemix.net/data/helo' failed. IBMBLUEMIX-0300E: Request by com.ibm.mobile.services.data.IBMData was rejected by MAS.  Status=401, Response={"error":"You are not authorized.","status":"failure"}
    .
11-03 19:42:53.539  31488-31508/com.ibm.bluelist E/getToken(34252)﹕ Server rejected request for with status code 401
    com.ibm.mobile.services.data.internal.HttpFailure: Http Response Code: 401
            at com.ibm.mobile.services.data.internal.Connection.getToken(Connection.java:199)
            at com.ibm.mobile.services.data.internal.Connection.access$400(Connection.java:43)
            at com.ibm.mobile.services.data.internal.Connection$Receiver.run(Connection.java:412)
11-03 19:42:53.539  31488-31508/com.ibm.bluelist E/Connection:Receiver(34252)﹕ Http Response Code: 401
    com.ibm.mobile.services.data.internal.HttpFailure: Http Response Code: 401
            at com.ibm.mobile.services.data.internal.Connection.getToken(Connection.java:199)
            at com.ibm.mobile.services.data.internal.Connection.access$400(Connection.java:43)
            at com.ibm.mobile.services.data.internal.Connection$Receiver.run(Connection.java:412)
11-03 19:43:06.789  31488-31488/com.ibm.bluelist D/ViewRootImpl﹕ ViewPostImeInputStage ACTION_DOWN
11-03 19:43:12.339  31488-31488/com.ibm.bluelist D/ViewRootImpl﹕ ViewPostImeInputStage ACTION_DOWN
11-03 19:43:13.109  31488-32236/com.ibm.bluelist E/com.ibm.mobile.services.core.http.IBMMutableHttpRequest﹕ Request to 'https://winmobile.mybluemix.net/data/helo' failed. IBMBLUEMIX-0300E: Request by com.ibm.mobile.services.data.IBMData was rejected by MAS.  Status=401, Response={"error":"You are not authorized.","status":"failure"}
    .
11-03 19:43:13.109  31488-31509/com.ibm.bluelist E/getToken(34253)﹕ Server rejected request for with status code 401
    com.ibm.mobile.services.data.internal.HttpFailure: Http Response Code: 401
            at com.ibm.mobile.services.data.internal.Connection.getToken(Connection.java:199)
            at com.ibm.mobile.services.data.internal.Connection.access$400(Connection.java:43)
            at com.ibm.mobile.services.data.internal.Connection$Sender.run(Connection.java:516)
11-03 19:43:13.109  31488-31509/com.ibm.bluelist W/Connection:Sender(34253)﹕ com.ibm.mobile.services.data.internal.HttpFailure: Http Response Code: 401
            at com.ibm.mobile.services.data.internal.Connection.getToken(Connection.java:199)
            at com.ibm.mobile.services.data.internal.Connection.access$400(Connection.java:43)
            at com.ibm.mobile.services.data.internal.Connection$Sender.run(Connection.java:516)
11-03 19:43:13.109  31488-31509/com.ibm.bluelist E/MainActivity﹕ Exception : Http Response Code: 401

2 个答案:

答案 0 :(得分:1)

没有什么可以阻止你这样做。 Lua中的本地或非函数名称实际上是变量名称,它指向函数本身。 所以

之间没有任何区别
local function f1()
   ...
end

local f1 = function()  
                ... 
           end

在这两种情况下f1都在函数体的范围内。

但是,这样的替换不会改变任何外部引用

function f1()
    print("f1")
end

function f2()
     print("f2")
     f2 = f1
end

f = f2

f1(); f2(); f2() f();

将导致输出

 f1
 f2
 f1
 f2

请注意,如果您在声明中添加local关键字,则无需更改

答案 1 :(得分:1)

要重新定义函数本身内的函数,您需要在已为声明的变量中引用该函数,然后才能为该变量分配对该函数的引用。

第一个例子 - 如何不这样做 - 不起作用,因为“fx”不在fx中的范围,因为直觉暗示(对我而言)它不会。

坦率地说,我不知道如何准确地描述函数内部的“fx” - 但它似乎是一个全局变量,其范围在某种程度上“比”全局本地“声明更全局化。“

在全球空间,我总是认为这两者是等价的:

foo = 'bar';
local foo = 'bar';

准确地说,它们显然不是真正等效的,如果你有办法同时访问它们。第一个例子正是如此,这就是原因:

当你这样做时......

local myfunc = function () ...

......你到底在做什么?

第一次声明一个匿名函数,第二次声明“myfunc”和第三次设置“myfunc”作为对此的引用你刚刚创建的匿名函数。在函数开始存在之前,“local myfunc”尚不存在,因为声明它的语句尚未实际执行。 (至少,这就是我对它的看法。)

以下是说明这一点的非工作版本:

local fx = function ()
    print(fx);
    print("inside the original fx")
    fx = function() print "I was redefined" end
end

function f2()
     print("f2")
     f2 = fx
end

f = f2

print(fx);

fx(); fx(); f2(); f2() f();


function: 0x21a6140     -- original "fx" ref is in "global local fx"
nil                     -- inner "fx" -- NOT set on first iteration, so it
inside the original fx  -- can't be the same varliable
function: 0x21a6510     -- now it's set, but to new function,
inside the original fx  -- but the "global local fx" does not contain our new function
f2
function: 0x21a6510
inside the original fx
f2

第二个例子,我们首先声明本地fx,然后将其设置为对函数的引用。没有其他变化。

local fx;       -- declare before assignment
fx = function ()
    print(fx);
    print("inside the original fx")
    fx = function() print "I was redefined" end
end

function f2()
     print("f2")
     f2 = fx
end

f = f2

print(fx);

fx(); fx(); f2(); f2() f();


function: 0x2188e50      -- original function
function: 0x2188e50      -- same reference, so this one *is* in scope
inside the original fx 
I was redefined          -- and redefining it works exactly as expected
f2
I was redefined
f2

所以,是的,有办法。您需要一个声明的全局局部变量,然后您需要将其设置为对该函数的引用,以便它在尝试重新定义它的函数的范围内。

以类似的方式,f2函数无法重新定义自身。它只会在f2运行时重新定义f2f2()内的含义。