खोज…


परिचय

पहले, मुझे कहना होगा। वहाँ एक कारण यह प्रॉक्सी बात है, इसकी प्रतीयमान उपयोगिता के बावजूद, इंटरनेट पर पर्याप्त प्रकाश डाला नहीं है।

आप इसका उपयोग यादृच्छिक श्रेणी / उदाहरण की यादृच्छिक संपत्ति देखने के लिए नहीं कर सकते हैं। आपको केवल प्रॉक्सी वर्ग को उप-वर्ग करके इस तकनीक का उपयोग करने की अनुमति है।

कुछ ऑपरेशन अपवादों की अपेक्षा नहीं करते हैं, इसलिए आपको पूरी तरह से समझने की आवश्यकता है कि आप क्या कर रहे हैं और क्यों कर रहे हैं, और आपका कोड बिल्कुल साफ और त्रुटि रहित होना चाहिए।

कार्यान्वयन

प्रॉक्सी क्लास के बारे में दूसरी बात, और यह इतना लोकप्रिय क्यों नहीं है, यह एक समस्या को थाह देना मुश्किल है, जो कि एक गतिशील वर्ग को अपने गतिशील गुणों और विधियों के लिए सबसे उपयुक्त समाधान के रूप में उपयोग करने योग्य है। जब भी मैंने प्रॉक्सी का उपयोग करने की कोशिश की, मैंने कुछ और, सरल और अधिक नियंत्रणीय का सहारा लिया।

हालाँकि, हमें निराश नहीं होना चाहिए। मुझे पायथन में सूचकांकों [-1], [-2] आदि द्वारा अंतिम सरणी तत्वों को संबोधित करने का विचार पसंद है। एक बड़ी उपलब्धि नहीं हो सकती है, लेकिन यह अच्छा लगता है कि लंबे और अनाड़ी के बजाय कुछ का उपयोग करें [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