« Monad and RSS | Main | Monad and RSS, Part 2 »

June 26, 2005

Discovering Objects in Monad

One of the nicest features of Monad is how it lets you discover the properties of objects.

Consider the get-feeds.msh script I talked about yesterday, at the point where I assign the variable $rssdata. Now it turns out I could have written those four lines in one, like this:

$rssdata = [xml]$(new-object System.Net.WebClient).DownloadString("http://www.proudlyserving.com/index.xml")

But what I want to talk about is what I did to write the next part of the script. I wasn't sure what the $rssdata object would look like (although it matches the tag heirarchy in the RSS). So what I did was take my script and change the line from

$rssdata = [whatever]


$global:rssdata = [whatever]

Then when I ran the script, it assigned $rssdata as a global variable and then exited the script. This meant $rssdata was available outside the script, after it exited (the normal scope for variable declared within a script is local to the script, so they go away when the script exits).

Now I could type at the interactive prompt and start playing around with the $rssdata variable to see what it contained, and what the script should do next. First I did the basic:

$rssdata | get-member

which prints out

    TypeName: System.Xml.XmlDocument

Name                        MemberType Definition
----                        ---------- ----------
ToString                    CodeMethod static String XmlNode(MshObject insta...
add_NodeChanged             Method     Void add_NodeChanged(XmlNodeChangedEv...
add_NodeChanging            Method     Void add_NodeChanging(XmlNodeChangedE...
Clone                       Method     XmlNode Clone()
rss                         Property   System.Xml.XmlElement rss {get;}
xml                         Property   System.String xml {get;set;}

(I cut a bunch of methods out, but you get the idea. I could also consult MSDN for documentation on the System.Xml.XmlDocument type). Now the rss property looks interesting, so I can try:

$rssdata.rss | get-member

and see what properties (and methods) that shows. I can also just type


by itself and uses the default formatter to display the properties:

version                                 channel
-------                                 -------
2.0                                     channel

which again gives me an idea of what lies beneath. Eventually, after playing around with it, I can figure out what I want the script to do, add it to the end, make $rssdata default scope again, and take the exit line out of the script.

Posted by AdamBa at June 26, 2005 09:24 PM

Trackback Pings

TrackBack URL for this entry:


Why is it called get-member rather than get-childitem?

Posted by: Ziv Caspi at June 26, 2005 10:53 PM

The XML support converts the XML into an object. I suppose you could view the object as a namespace which could then be viewed via providers (and hence via get-childitem), but it wasn't supported that way. It would be a little unclear since the objects are ephemeral so what would it mean to define a drive, say, on an object.

Instead a specific cmdlet, get-member, was written to discover properties of objects.

- adam

Posted by: Adam Barr at June 27, 2005 03:26 PM

But that's exactly my point. As long as I have a "handle" to some object X containing other objects, I don't need to know how to reach X from some universal root in order to get its children. The fact that Monad treats file system directory traversal and registry keys traversal uniformly is a perfect example for that. A technical implementation detail (like what can be viewed as a provider and what cannot) shouldn't be allowed to change the model exposed to the user, if possible.

Posted by: Ziv Caspi at June 30, 2005 11:37 PM