ActionScript 3
프록시 클래스 사용
수색…
소개
먼저, 나는 말해야 만합니다. 이 프록시 일이, 그 보이는 유용성에도 불구하고, 인터넷에서 충분히 강조되지 않는 이유가있다.
임의의 클래스 / 인스턴스의 무작위 속성을보기 위해 사용할 수 없습니다 . Proxy 클래스를 하위 클래스 화하여이 기술을 사용할 수 있습니다.
일부 작업은 예외를 기대하지 않으므로 수행중인 작업과 수행중인 작업을 완전히 이해해야하며 코드 는 절대적으로 깨끗하고 오류가 없어야 합니다 .
이행
Proxy 클래스에 대한 또 다른 이유와 왜 그렇게 인기가없는 이유는 가장 적합한 솔루션으로 동적 속성 및 메서드에 대한 제어 가능한 액세스 권한을 가진 동적 클래스가 정확히 필요한 문제를 파악하는 것이 다소 어렵다는 것입니다. Proxy를 사용하려고 할 때마다, 나는 더 단순하고 제어하기 쉬운 다른 것에 의존하게되었습니다.
그러나 낙심하지 마십시오. 필자는 Python 에서 [-1], [-2] 등의 인덱스를 사용하여 마지막 배열 요소를 처리한다는 생각을 좋아합니다. 커다란 위업은 아니지만 길고 서투른 someArray [someArray.length - 1] 보다는 오히려 그것을 사용하는 것이 좋다고 느낍니다 . 우리가 그것에 대해 무엇을 할 수 있는지 알아 봅니다.
package
{
import flash.utils.Proxy;
import flash.utils.flash_proxy;
/**
* Pyaray the Tentacled Whisperer of Impossible Secrets.
*/
dynamic public class PyArray extends Proxy
{
private var data:Array;
public function PyArray(...args:Array)
{
if (args.length == 0)
{
data = new Array;
}
else if ((args.length == 1) && (args[0] is Array))
{
data = args[0];
}
else
{
data = args;
}
}
// This is a getter proxy to all the available Array
// elements and properties and, sometimes, methods.
override flash_proxy function getProperty(name:*):*
{
var anIndex:int = name;
// Handle the int indices of the Array elements.
if (anIndex == name)
{
// Handle the -1, -2, etc indexing.
if (anIndex < 0) anIndex += data.length;
if (anIndex >= data.length) return null;
if (anIndex < 0) return null;
return data[anIndex];
}
// Handle the existing public Array properties.
if (data.hasOwnProperty(name)) return data[name];
// Handle the Array methods addressed via ["member"] access.
try
{
if (data[name] is Function) return data[name];
else throw new Error;
}
catch (fail:Error)
{
trace("[PyArray] is unable to resolve property \"" + name + "\".");
}
return null;
}
// This will set either elements, or settable properties.
override flash_proxy function setProperty(name:*, value:*):void
{
var anIndex:int = name;
// Handle the int indices of the Array elements.
if (anIndex == name)
{
// Handle the -1, -2, etc indexing.
if (anIndex < 0) anIndex += data.length;
// In case the element index is out of range,
// the PyArray will extend its data Array.
// if (anIndex >= data.length) return;
if (anIndex < 0) return;
data[anIndex] = value;
return;
}
// Handle the existing (or dynamic) public Array properties.
try
{
data[name] = value;
}
catch (fail:Error)
{
trace("[PyArray] is unable to set property \"" + name + "\".");
}
return;
}
// This allows to delete PyArray elements with "delete" operator.
override flash_proxy function deleteProperty(name:*):Boolean
{
var anIndex:int = name;
// Handle the int indices of the Array elements.
if (anIndex == name)
{
// Handle the -1, -2, etc indexing.
if (anIndex < 0) anIndex += data.length;
if (anIndex >= data.length) return false;
if (anIndex < 0) return false;
data.splice(anIndex, 1);
return true;
}
// Handle the dynamic public Array properties.
try
{
delete data[name];
return true;
}
catch (fail:Error)
{
trace("[PyArray] is unable to delete the \"" + name + "\" property.");
}
return false;
}
// This proxies any attempt to call a method on PyArray directly to data Array, thus
// all Array methods (including "toString" method called through trace) are available.
override flash_proxy function callProperty(name:*, ...rest):*
{
try
{
return (data[name] as Function).apply(data, rest);
}
catch (fail:Error)
{
trace("[PyArray] is unable to resolve method \"" + name + "\".");
return null;
}
}
// This allows PyArray to handle for..in and for..each..in loops.
// The initial call starts with zero, so we need to do this +1 -1 magic
// in order for enumeration to work correctly. I'm not happy with this either.
override flash_proxy function nextNameIndex(index:int):int
{
if (index >= data.length) return 0;
else return index + 1;
}
// This method handles the for..in loop.
override flash_proxy function nextName(index:int):String
{
return (index - 1).toString();
}
// This method handles the for..each..in loop.
override flash_proxy function nextValue(index:int):*
{
return data[index - 1];
}
}
}
용법
package
{
import flash.display.Sprite;
/**
* Daemonette of Slaanesh.
*
* It is minor female demon, vaguely human-like, but with crab-like pincers instead of hands.
* She wears a rather indecent skimpy leather bikini, moves quickly and casts deadly spells!
*/
public class Slaanesh extends Sprite
{
public function Slaanesh()
{
// Lets initialize the PyArray.
var PA:PyArray = new PyArray(1,2,3,4,5,4,3,2,1,"Foo");
// Basic check: get the last element.
trace(PA[-1]);
// output:
// Foo
// This will map to the 0-based third element.
trace(PA[2.0]);
// output:
// 3
// This should not get us anywhere.
trace(PA[2.1]);
// output:
// [PyArray] is unable to resolve property "2.1".
// null
// This should return the length of the data Array.
trace(PA["length"]);
// output:
// 10
// This should return the length of the data Array.
// This will not compile unless PyArray class is marked "dynamic".
trace(PA.length);
// output:
// 10
// This will map to indexOf method of data Array via getProperty method.
trace(PA["indexOf"]);
// output:
// function Function() {}
// This will map to indexOf method of data Array via getProperty method.
// This will not compile unless PyArray class is marked "dynamic".
trace(PA.indexOf);
// output:
// function Function() {}
// This is a try to access a non-existent property.
// This will not compile unless PyArray class is marked "dynamic".
trace(PA.P124);
// output:
// [PyArray] is unable to resolve property "P124".
// null
// This is a try to call a non-existent method via callProperty method.
// This will not compile unless PyArray class is marked "dynamic".
trace(PA.P124());
// output:
// [PyArray] is unable to resolve method "P124".
// null
// Basic check: calling a proxied method via callProperty method.
trace(PA.indexOf(5));
// output:
// 4
// An attempt to replace an Array method with a random value.
// This will not compile unless PyArray class is marked "dynamic".
PA.indexOf = 123;
// output:
// [PyArray] is unable to set property "indexOf".
// An attempt to assign a random value to a random property.
// It will succees because Array, as a dynamic class, allows so.
// This will not compile unless PyArray class is marked "dynamic".
PA.indexOfz = 123;
trace(PA.indexOfz);
// output:
// 123
// An attempt to assign an Array element via negative indexing.
// This trace works fine because toString method is also proxied.
PA[-3] = "Hello";
trace(PA);
// output:
// 1,2,3,4,5,4,3,Hello,1,Foo
// An attempt to delete Array elements via normal and negative indexing.
// This operation is mapped via deleteProperty method.
delete PA[-4]; // deletes "3" before "Hello"
delete PA[0]; // deletes "1" at the start.
trace(PA);
// output:
// 2,3,4,5,4,Hello,1,Foo
// An attempt to delete a non-dynamic method reference.
// There's no error output, AS3 must be handling this internally.
delete PA.indexOf;
trace(PA.indexOf);
// output:
// function Function() {}
// An attempt to set an element out of index range.
PA[10] = "123abc";
trace(PA);
// output:
// 2,3,4,5,4,Hello,1,Foo,,,123abc
var aText:String;
// This is a test of for..in loop, Array elements are
// enumerated via nextName and nextNameIndex methods.
aText = ""
for (var aKey:String in PA)
aText += aKey + ":" + PA[aKey] + " ";
trace(aText);
// output:
// 0:2 1:3 2:4 3:5 4:4 5:Hello 6:1 7:Foo 8:undefined 9:undefined 10:123abc
// This is a test of for..each..in loop, Array elements are
// enumerated via nextValue and nextNameIndex methods.
aText = "";
for each (var aValue:* in PA)
aText += aValue + " ";
trace(aText);
// output:
// 2 3 4 5 4 Hello 1 Foo undefined undefined 123abc
}
}
}
Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow