From: ekkehard.horner on 7 Aug 2010 15:53 Peter Olcott schrieb: > On 8/6/2010 7:07 PM, Mayayana wrote: >> I don't know if you can actually create an array >> of objects. It sounds like what you want is >> a Dictionary. But if you want an object hierarchy >> it might be better to use classes. >> >> | Can a Component written in VBScript return an array of different Object >> | types? In other words the elements of the array are not the same type. >> | >> >> > How would a dictionary of COM components work in VBScript? > As I told Tom showed I will prove to you, there are no problems whatsoever to store different (types of) objects in VBScript arrays. Mayayana's speculations are just that. This is a bare bone .wsc: <?xml version="1.0"?> <component> <registration description="Quak" progid="Quak.WSC" version="1.00" classid="{d0ccb637-bd0c-4c90-a4bd-7473f499d35a}"> </registration> <public> <method name="getWhatever" /> </public> <script language="VBScript"> <![CDATA[ ' OO - Inheritance = Repeat Yourself ' (Here I *want* distinct classes, but in VBScript I *can't* have a hierarchy) Class cDuck : Function speak() : speak = "Duck: quak" : End Function : End Class Class cParrot : Function speak() : speak = "Parrot: quak" : End Function : End Class Class cFrog : Function speak() : speak = "Frog: quak" : End Function : End Class Function getWhatever() getWhatever = Array( _ New cDuck _ , New cParrot _ , New cFrog _ ) End Function ]]> </script> </component> and this .wsf shows how scripting languages with tolerant type systems can use the VBScript array: <?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?> <package> <job id="testquak"> <?job error="true" debug="true" ?> <script language="Python"> <![CDATA[ # ############################################################################ import win32com.client def PYQuak(): oQuak = win32com.client.Dispatch( "Quak.WSC" ) aWhatever = oQuak.getWhatever() for oWhatever in aWhatever: print oWhatever.speak() # ############################################################################ ]]> </script> <script language="Perlscript"> <![CDATA[ # ############################################################################ use strict; use warnings; use Win32::OLE; sub PLQuak { my $oQuak = Win32::OLE->new( 'Quak.WSC' ); my @aWhatever = @{$oQuak->getWhatever()}; foreach (@aWhatever) { print $_->speak(), "\n"; } } # ############################################################################ ]]> </script> <script language="JScript"> <![CDATA[ // ########################################################################### function JSQuak() {; var oQuak = new ActiveXObject( "Quak.WSC" ); var aWhatever = new VBArray( oQuak.getWhatever() ).toArray(); for (var i = 0; i < aWhatever.length; ++i) { WScript.Echo( aWhatever[ i ].speak() ); } } // ########################################################################### ]]> </script> <script language="VBScript"> <![CDATA[ ' ############################################################################ Option Explicit ''# MAIN ' ############################################################################ WScript.Quit doMain() ''= doMain() - ' ============================================================================ Function doMain() doMain = 1 WScript.Echo "----------- VBScript -----------" Dim oQuak : Set oQuak = CreateObject( "Quak.WSC" ) Dim aWhatever : aWhatever = oQuak.getWhatever() Dim oWhatever For Each oWhatever In aWhatever WScript.Echo oWhatever.Speak() Next WScript.Echo "----------- JScript -----------" JSQuak WScript.Echo "----------- Perl -----------" PLQuak WScript.Echo "----------- Python -----------" PYQuak doMain = 0 End Function ' ############################################################################ ]]> </script> </job> </package> output: cscript //D testquak.wsf ----------- VBScript ----------- Duck: quak Parrot: quak Frog: quak ----------- JScript ----------- Duck: quak Parrot: quak Frog: quak ----------- Perl ----------- Duck: quak Parrot: quak Frog: quak ----------- Python ----------- Duck: quak Parrot: quak Frog: quak As you can see, there may be special efforts involved to make the VBScript array accessible: (JScript) var oQuak = new ActiveXObject( "Quak.WSC" ); var aWhatever = new VBArray( oQuak.getWhatever() ).toArray(); I wouldn't be sure that such features exist in every language that claims to be able to use COM objects. Scripting languages tend to be tolerant wrt types (late binding); they will try to invoke methods on an object trusting the programmer. Compiled languages like the members of the .NET family rely on type information (early binding). You probably can tell a C# or VB.NET program the the thingy you get back from oQuak.getWhatever() is an array of Objects, but I doubt that a strictly typed language will let you call .speak() on something it knows only as an Object. Have a look at http://www.dotnet247.com/247reference/msgs/31/156831.aspx to see a discussion about .WSC and .NET. Perhaps you can use Reflection and Invoke as a workaround or the new Dynamic Typing of .NET 4.0, but I wouldn't start investing work in VBScript components without *proof* that it really works in the languages to be (claimed as) supported.
From: Mayayana on 8 Aug 2010 23:03 | there are no problems whatsoever to store different (types of) | objects in VBScript arrays. Mayayana's speculations are just that. Yes, I see that you're right: Dim A1(3), i, s A1(0) = "eee" A1(1) = 3 A1(2) = Array(1, 2, 3) Set A1(3) = CreateObject("Shell.Application") For i = 0 to 3 s = s & typename(A1(i)) & vbCrLf Next MsgBox s Set A1(3) = Nothing I'm used to VB, where arrays work the same way but are normally strongly typed. Personally, though, I think I'd still use a Dictionary to reference a variety of objects.
From: ekkehard.horner on 9 Aug 2010 06:42 Mayayana schrieb: > | there are no problems whatsoever to store different (types of) > | objects in VBScript arrays. Mayayana's speculations are just that. > > Yes, I see that you're right: > > Dim A1(3), i, s > A1(0) = "eee" > A1(1) = 3 > A1(2) = Array(1, 2, 3) > Set A1(3) = CreateObject("Shell.Application") > > For i = 0 to 3 > s = s& typename(A1(i))& vbCrLf > Next > MsgBox s > Set A1(3) = Nothing > > I'm used to VB, where arrays work the same > way but are normally strongly typed. Personally, > though, I think I'd still use a Dictionary to > reference a variety of objects. > > It goes without saying that you may do whatever you like, but in my opinion there is no reason to use a dictionary if you want to store different kinds of objects in a collection. What colection you choose should not be determined by the nature of the elements you want to store but by the services/features of the collection you need. Nothing in the OT's postings indicates that he needs to access the elements 'by name' (as oposed to 'by number/index'). If the shortcomings of the VBScript array (the need to copy when growing the array or when changing elements in nested arrays) become a problem, switching to the .NET Arraylist may be a way out.
From: Mayayana on 9 Aug 2010 08:15 | What colection you choose should not be determined by the nature | of the elements you want to store but by the services/features of | the collection you need. Nothing in the OT's postings indicates | that he needs to access the elements 'by name' (as oposed to 'by | number/index'). | Does it really make sense to you to access a number of disparate objects by remembering their numeric offset in an array? As you've shown, it can be done. The next question is "why?". I don't use a Dictionary often, but I do find them very useful. And the author of O'Reilly's VB book says they're actually notably faster than a Collection. In any case, I appreciate your generosity of spirit in allowing me to do things the wrong way. :) But it seems that the real point was never addressed here: Peter Olcott never described what he's actually trying to do. And storing object references is not a good idea in the first place. (As an example, I once wrote code that stored references to the IE objects representing all open folders. On Win98, if a folder was closed before the object was released, Explorer would crash.) So we're really just discussing the variety of data types.
From: ekkehard.horner on 9 Aug 2010 10:25 Mayayana schrieb: > | What colection you choose should not be determined by the nature > | of the elements you want to store but by the services/features of > | the collection you need. Nothing in the OT's postings indicates > | that he needs to access the elements 'by name' (as oposed to 'by > | number/index'). > | > > Does it really make sense to you to access > a number of disparate objects by remembering > their numeric offset in an array? As you've > shown, it can be done. The next question is "why?". > Yes, it makes sense to me to access the elements of a collection by number/index, because I don't need to equate "accessing by index" with "remembering the index". > I don't use a Dictionary often, but I do find > them very useful. And the author of O'Reilly's > VB book says they're actually notably faster > than a Collection. > I use dictionaries often - when it makes sense to do so. For example, if you want to determine the frequencies of words in a text, it's convenient to use the words as keys and the counts as values in a dictionary. dicFreq( CurrentWord ) = dicFreq( CurrentWord ) + 1 beats using a function that loops over the first column of a two-dimensional array to find (or append) the CurrentWord and update the corresponding cell in the second columns every time. (BTW: in both cases there is no need for the programmer to remember the 'names' or the indices of the items) I doubt that an author of an O'Reilly book would get away with stating that a dictionary is "faster than a Collection", as this is like saying that a Prius is faster than a car. (Nevertheless, I'd like to get a usable reference.) For people interested in the efficieny of most basic operations on arrays and dictionaries: Dim nUB : nUB = 333333 WScript.Echo nUB, "elms Array vs. Dictionary" cudDic nUB cudArray nUB Sub cudArray( nUB ) Dim nTime nTime = Timer() ReDim aX( nUB ) WScript.Echo "ReDim:", FormatNumber( Timer() - nTime, 6 ) nTime = Timer() Dim nIdx For nIdx = 0 To nUB aX( nIdx ) = nIdx Next WScript.Echo "Fill: ", FormatNumber( Timer() - nTime, 6 ) nTime = Timer() For nIdx = 0 To nUB aX( nIdx ) = aX( nIdx ) + 1 Next WScript.Echo "Upd: ", FormatNumber( Timer() - nTime, 6 ) End Sub Sub cudDic( nUB ) Dim nTime nTime = Timer() Dim dicX : Set dicX = CreateObject( "Scripting.Dictionary" ) WScript.Echo "Creat:", FormatNumber( Timer() - nTime, 6 ) nTime = Timer() Dim nIdx For nIdx = 0 To nUB dicX( nIdx ) = nIdx Next WScript.Echo "Fill: ", FormatNumber( Timer() - nTime, 6 ) nTime = Timer() For nIdx = 0 To nUB dicX( nIdx ) = dicX( nIdx ) + 1 Next WScript.Echo "Upd: ", FormatNumber( Timer() - nTime, 6 ) End Sub output: 333333 elms Array vs. Dictionary Creat: 0.000000 Fill: 3.222656 Upd: 6.839844 ReDim: 0.027344 Fill: 0.101563 Upd: 0.207031 > In any case, I appreciate your generosity of > spirit in allowing me to do things the wrong way. :) > All I hope for is to make people think twice before they base important decisions on your assumptions. > But it seems that the real point was never > addressed here: Peter Olcott never described > what he's actually trying to do. And storing > object references is not a good idea in the > first place. (As an example, I once wrote code > that stored references to the IE objects representing > all open folders. On Win98, if a folder was closed > before the object was released, Explorer would crash.) > Rephrased as "be careful not to use your references when the refered to objects are dead" - agreed. > So we're really just discussing the variety of > data types. > > >
First
|
Prev
|
Pages: 1 2 3 Prev: How to "harvest" the contents of a hidden or "about blank" web Next: start and monitor |