2008-11-04 2 views
1

В функции actioncript (method) у меня есть доступ к arguments.caller, который возвращает объект Function, но я не могу узнать имя функции, представленной этим объектом Function. Его функция toString() просто возвращает [Function], и я не могу найти никаких других полезных аксессуаров, которые дают мне это ... Справка: -/Есть ли способ найти имя вызывающей функции в actionscript2?

ответ

0

Я нашел ответ, и я вставлю его ниже.

@fenomas: да, вы правы, конечно, функции - это просто объекты, а то, что я ищу, - это имя ссылки на них (если существует, то есть функция не является анонимной). Вы также правы, что в целом это не похоже на лучший способ программирования ;-) Но мой сценарий особенный: я хочу реализовать класс Checks (аналогичный C CHECK) с помощью таких методов, как Check.checkTrue и Checks. checkRef, в котором, когда сбой проверки, я получаю приятный след. Трассировки появятся только в отладочной версии, а не в выпуске.

Я использую MTASC, а приведенный ниже код работает только с MTASC. Его также следует использовать только для целей отладки и не выпускать. Техника состоит в том, чтобы перебирать _global и находить функцию, равную моей вызывающей функции. Это хак, который не всегда работает (анонимный), но в большинстве случаев он мне очень нравится.

39: /** 
40: * Checks that cond is true. Use this method to validate that condition 
41: * cond holds. 
42: * If cond is false, traces a severe message and returns false to indicate 
43: * check failure. 
44: * 
45: * @param cond the contition expected to be true 
46: * @param msg the message to emit in case the condition is false. 
47: * 
48: * @return false is cond is false 
49: */ 
50: public static function checkTrue(cond:Boolean, msg:String):Boolean { 
51:  if (!cond) { 
52:  trace("severe", "CHECK FAILED at " + 
53:   **getFunctionName(arguments.caller)** + ":\n" + msg); 
54:  } 
55:  return cond; 
56: } 


94: /** 
95: * Gets the name of the function func. 
96: * Warning: Use this only in debug version, not in release 
98: * 
99: * @return The full package path to the function. null if the function 
100: *  isn't found. 
101: */ 
102: private static function getFunctionName(func:Function):String { 
103:  var name:String = getFunctionNameRecursive(func, _global); 
108:  return name; 
109: } 
110: 
111: /** 
112: * Gets the name of the function func by recursively iterating over root. 
113: * Warning: Use this only in debug version, not in release 
114: */ 
115: private static function getFunctionNameRecursive(func:Function, 
116:  root:Object):String { 
117:  if (!root) { 
118:  return null; 
119:  } 
120: 
121:  // Iterate over classes in this package 
122:  // A class is a function with a prototype object 
123:  for (var i:String in root) { 
124:  if (root[i] instanceof Function && root[i].prototype != null) { 
125:   // Found a class. 
126:   // Iterate over class static members to see if there's a match 
127:   for (var f:String in root[i]) { 
128:   if(root[i][f] == func) { 
129:    return i + "." + f; 
130:   } 
131:   } 
132:   // Loop over the class's prototype to look for instance methods 
133:   var instance:Object = root[i].prototype; 
134:   // Reveal prototype's methods. 
135:   // Warning: Not to be used in production code!!! 
136:   // The following line make all the instance attributes visible to the 
137:   // for-in construct. The "n" value is 8 which means "unhide" 
138:   // See http://osflash.org/flashcoders/undocumented/assetpropflags 
139:   // This operation is later undone by setting the "n" to 1 which means 
140:   // "hide" 
141:   _global.ASSetPropFlags(instance, null, 8, 1); 
142:   for (var f:String in instance) { 
143:   if(instance[f] == func) { 
144:    return i + "." + f; 
145:   } 
146:   } 
147:   // And hide instance methods again 
148:   // This line undoes the previous ASSetPropFlags 
149:   _global.ASSetPropFlags(instance, null, 1, false); 
150:  } 
151:  } 
152: 
153:  // Iterate over sub packages. Sub packages have type "object" 
154:  for (var i:String in root) { 
155:  if (typeof(root[i]) == "object") { 
156:   var name:String = getFunctionNameRecursive(func, root[i]); 
157:   if (name) { 
158:   return i + "." + name; 
159:   } 
160:  } 
161:  } 
162:  return null; 
163: } 
1

Функция - это просто объект, подобный любому другому - это не имеют «имя» само по себе; он имеет только имя в том смысле, что вы можете сделать одну или несколько ссылок на него. Если вы спрашиваете, как получить имя ссылки, по которой была вызвана функция, тогда нет общего способа сделать это. (В конце концов, функция может быть объявлена ​​анонимно, и в этом случае она не имеет имени вообще.)

Возможно, было бы лучше изучить, почему вам нужно знать имя функции и выяснить какой-либо другой способ передачи или получить доступ к информации, которую вы пытаетесь извлечь из этого имени. Передача дополнительного параметра может быть одним из подходов, но это зависит от того, что вы делаете.

0

Насколько я знаю, не в AS2 AS3 только.

Смежные вопросы