Saturday, May 01, 2004

This is about a small tool I have been using for a while now to let me talk to the WMI (Windows Management Instrumentation) object model exposed by the Windows operating system. WMI is used for various management related tasks and is a very powerful API.

 

I wanted to write the script at one sitting (and not a long one) and so a scripting language was an obvious choice. This could have been written in C++ or C# or any COM interface aware language also. I started of with a Ruby version, but decided to quit on that because the Ruby libraries for interfacing with OLE were not very stable when it came to WMI programming. I believe that is being fixed now. Perl was good choice because it was sufficiently dynamic and more importantly it had stable libraries. The source here can be readily translated to VBScript or JScript versions also. If you do so, drop me a mail.

 

I had mailed about this script to the user groups in the past, but I got a feeling that I had done no justice to what this script and WMI could actually achieve. Hence this article.

 

Download and Docs

You can download the script here, or simply copy paste it and save it from this article. To make this work, you need to have Perl on your machine. Perl can be downloaded for free from here.

 

If you are new to WMI and what to have a good understanding of what is available I suggest you take a look at:

·         WMI Scripting Primer Part 1 Part 2 Part 3

·         The MSDN site on scripting is a good resource: http://msdn.microsoft.com/scripting

·         Scriptomatic: playing around with this HTA application for auto-generating WMI scripts is also lots of fun

·         My previous blog entry Bangalore User Group – WSH, WMI and System.Management has some beginner level scripts that I had demoed at one the UG meetings.

 

What can you do with wmi.pl ?

 

The following is a brief description of what you can do with the wmi.pl.

 

Listing Instances

> wmi.pl

Lists all the running processes on your computer. The out looks a little like this:

D:\scr>wmi.pl

1       System Idle Process

2       System

3       SMSS.EXE

4       CSRSS.EXE

5       WINLOGON.EXE

6       SERVICES.EXE

 

Specifying properties to display

> wmi.pl -executablepath

Lists all the processes as well as their physical paths on disk.

D:\scr>wmi.pl -executablepath

1       System Idle Process

2       System

3       SMSS.EXE        C:\WINNT\System32\smss.exe

4       CSRSS.EXE

5       WINLOGON.EXE    C:\WINNT\system32\winlogon.exe

6       SERVICES.EXE    C:\WINNT\system32\services.exe

7       LSASS.EXE       C:\WINNT\system32\lsass.exe

8       svchost.exe     C:\WINNT\system32\svchost.exe

 

> wmi.pl -< property name >

Lists all the processes with the specified property of the process displayed. This requires some explanation. The processes I refer to here are instance of the WMI class called Win32_Process. You can look at the documentation for the class to see what properties this class supports. Or you can you some of the reflection capabilities of WMI which I have discussed in the next usage sample. The ‘executablepath’ that was shown earlier was one such property. There are several others that the Win32_Process class supports.

This shows the process id of each process as well as how many threads each process currently has. Powerful?

D:\scr>wmi.pl -processid -threadcount

1       System Idle Process     0       1

2       System  8       46

3       SMSS.EXE        152     6

4       CSRSS.EXE       176     12

5       WINLOGON.EXE    172     19

6       SERVICES.EXE    224     37

7       LSASS.EXE       236     18

8       svchost.exe     420     12

9       spoolsv.exe     452     11

 

Examining Classes for Properties and Methods

> wmi.pl ?

Lists all the properties and methods available for the process class. This uses the reflection capabilities of WMI. It examines the Win32_Process class and tells you what properties and methods the class provides. So you can use the information retrieved to know what property name parameters you can use. The output here is edit, the Win32_Process class support many more properties than shown here.

D:\scr>wmi.pl ?

Win32_Process Properties : -----------------------------

1       Caption

2       CreationClassName

3       CreationDate

4       CSCreationClassName

5       CSName

6       Description

7       ExecutablePath

8       ExecutionState

44      WriteTransferCount

Win32_Process Methods : -----------------------------

1       Create

2       Terminate

3       GetOwner

4       GetOwnerSid

So it is easy to see that ‘wmi.pl – creationdate’ is a valid query. Exploring this API can give you lots of useful information. I shall shortly show you what we can do with the methods.

 

Displaying all the Properties of a Class

> wmi.pl -*

This will list all available information about every process on the system. Information such as memory usage, kernel usage, thread count etc are available. In case you want to see a lot of information about every process, the tabular view (generated by specifying property names in the command line) maybe inadequate. This is again highly truncated output that is shown.

51

 Caption = perl.exe

 CreationClassName = Win32_Process

 CreationDate = 20040430233435.908750+330

 CSCreationClassName = Win32_ComputerSystem

 CSName = RMZ10F01

 Description = perl.exe

 ExecutablePath = D:\RoshanJ\Progs\perl\bin\perl.exe

 ExecutionState =

 Handle = 3368

 HandleCount = 106

PeakWorkingSetSize = 5586944

 Priority = 8

 PrivatePageCount = 2265088

 ProcessId = 3368

 QuotaNonPagedPoolUsage = 4780

 QuotaPagedPoolUsage = 20416

 QuotaPeakNonPagedPoolUsage = 5176

 QuotaPeakPagedPoolUsage = 20420

 ReadOperationCount = 54

 

 

Specifying classes to use

> wmi.pl < class name>

So far we have seen that wmi.pl retrieves information about the Win32_Process class. What about all the other information that WMI? The Perl script basically has Win32_Process hard coded as the default class to use. To provide all the behavior that you saw above, taking place for some other class (other than Win32_Process), simply specify the name of that class at the command line.

 

Doing so will cause the rest of the parameters to act for the given class name. For example Win32_Share is the class name for shares of your computer. So ‘wmi.pl win32_share’ will list all the shares and ‘wmi.pl win32_share –path’ will list the share names and their physical paths on your computer.

D:\scr>wmi.pl win32_share

2       System.DDL

4       ut

7       dotnet-talk

8       install

10      ftproot

and (notice we pass –path here, so ‘path’ must be a property of win32_share)

D:\scr>wmi.pl win32_share -path

2       System.DDL      D:\RoshanJ\Homepage\work\System.DDL

4       ut      D:\ut

7       dotnet-talk     D:\dotnet-talk

8       install D:\RoshanJ\install

10      ftproot C:\Inetpub\ftproot

To take a look at what Win23_Share provides

D:\scr>wmi.pl win32_share ?

win32_share Properties : -----------------------------

1       AccessMask

2       AllowMaximum

3       Caption

4       Description

5       InstallDate

6       MaximumAllowed

7       Name

8       Path

9       Status

10      Type

win32_share Methods : -----------------------------

1       Create

2       SetShareInfo

3       Delete

 

Win32_Service represents services on your computer. Win32_LogicalDisk represent drives on your system and so on. All available properties about a win32_LogicalDisk maybe queried by typing ‘wmi.pl win32_logicaldisk ?’, similar to the above sample with Win32_Share. Simple?

 

Now you may ask, how you can know what classes are available. Read on.

 

Examining Namespaces for Classes and Namespaces

> wmi.pl dir

In WMI classes are organized into namespaces. The script wmi.pl is configured to use the namespace ‘root/cimv2’ by default. The above line will list all the classes and nexted namespaces in a namespace. This is a rather huge list so you may want to save this into a text file. Once you find a class that you think is useful, you can query information about the classes listed here by specifying the class name and using the ‘?’ parameter.

D:\scr>wmi.pl dir

root/cimv2 Classes : -----------------------------

441     \\RMZ10F01\ROOT\CIMV2:Win32_DeviceBus

442     \\RMZ10F01\ROOT\CIMV2:Win32_CIMLogicalDeviceCIMDataFile

443     \\RMZ10F01\ROOT\CIMV2:Win32_ShareToDirectory

444     \\RMZ10F01\ROOT\CIMV2:Win32_NetworkAdapterConfiguration

445     \\RMZ10F01\ROOT\CIMV2:Win32_NetworkAdapterSetting

446     \\RMZ10F01\ROOT\CIMV2:Win32_PortableBattery

447     \\RMZ10F01\ROOT\CIMV2:Win32_SystemSlot

448     \\RMZ10F01\ROOT\CIMV2:Win32_PortConnector

449     \\RMZ10F01\ROOT\CIMV2:Win32_PhysicalMemory

450     \\RMZ10F01\ROOT\CIMV2:Win32_SystemEnclosure

451     \\RMZ10F01\ROOT\CIMV2:Win32_BaseBoard

Win32_Process Namespaces : -----------------------------

1       Applications

2       ms_409

To redirect content to text file

D:\scr>wmi.pl dir > filename.txt

 

Specifying other Namespaces

> wmi.pl /ns:< namespace> < other parameters>

            You can change the namespace where the script should find the WMI class you mention by using the /ns: specification. This might be a little abstract to understand but consider this. The previous option ‘dir’ showed you only contents of the ‘root/cimv2’ namespace, if you wanted to see the contents of the ‘root’ namespace the you could use this feature.

D:\scr>wmi.pl /ns:root dir

root Classes : -----------------------------

1       \\RMZ10F01\ROOT:__SystemClass

2       \\RMZ10F01\ROOT:__NAMESPACE

3       \\RMZ10F01\ROOT:__Provider

4       \\RMZ10F01\ROOT:__Win32Provider

5       \\RMZ10F01\ROOT:__ProviderRegistration

6       \\RMZ10F01\ROOT:__ObjectProviderRegistration

7       \\RMZ10F01\ROOT:__ClassProviderRegistration

8       \\RMZ10F01\ROOT:__InstanceProviderRegistration

9       \\RMZ10F01\ROOT:__PropertyProviderRegistration

Win32_Process Namespaces : -----------------------------

1       DEFAULT

2       SECURITY

3       CIMV2

4       WMI

5       directory

6       MSAPPS10

7       NetFrameworkv1

8       MSAPPS

9       MSAPPS11

As you can see, the root namespace contains a namespace called the ‘cimv2’.

 

Here is an example that lists instances of the Win32_OleDbProvider which is part of the ‘root/msapps’ namespace.

D:\scr>wmi.pl /ns:root/msapps win32_oledbprovider

1       VSEE Versioning Enlistment Manager Proxy Data Source

2       MediaCatalogDB OLE DB Provider

3       Microsoft OLE DB Provider for SQL Server

4       Microsoft OLE DB Provider for DTS Packages

5       SQL Server Replication OLE DB Provider for DTS

6       MediaCatalogMergedDB OLE DB Provider

7       Microsoft ISAM 1.1 OLE DB Provider

8       Microsoft OLE DB Provider For Data Mining Services

9       MSDataShape

10      VSEE Versioning Enlistment Manager Proxy Data Source

 

Collecting data from remote computers

> wmi.pl @< computer name > [some other parameters]

All the commands that you saw so far were getting information about your computer. If you are on a network, WMI can let you gather such information about a remote computer as well.

Specifying a computer name or IP address preceded by an @ will cause the whole command to run on a remote system. To execute this successfully your current logged on user id should have admin rights on the remote system. Such a security check is essential because WMI can do potentially powerful and dangerous things such as stopping and starting of services, processes, access to disk partitions, bios etc.

The following command lists shares on a remote computer and shows you the physical paths of the share on that computer.

D:\scr>wmi.pl @machine01 win32_share -path

22      v0.2_dist       D:\v0.2_dist

23      ecma    D:\rotor_text\ecma

25      rotor_text      D:\rotor_text

26      ruby1.8 D:\RoshanJ\Progs\ruby1.8

27      1.0.0001.0020   D:\blog\blogx\1.0.0001.0020

 

Calling Methods on WMI classes

wmi.pl –terminate()

Will terminate every process on your system (that you have rights to terminate). I am not running this as a demo right now, just take my word for it.

If you remember the output of the ‘?’ parameter you might recollect that it displays properties and methods that are available for a class. Thus terminate() was a method of the Win32_Process class. Calling terminate on a process, as expected, would try to terminate it.

 

wmi.pl  -< property name >=< value > < method name>()

Often we do not want to want to call a method on every instance of a class. Like, would would not want to terminate() all the process, but say only a set of them. This is when the above syntax comes in useful. This will call the method specified on every instance of the specified class where the given property has the given value.

So if you want to terminate all the instances of Internet explorer that are running on your system you would say:

D:\scr>wmi.pl -name=iexplore.exe terminate()

Query = select * from Win32_Process where   name='iexplore.exe'

0 IEXPLORE.EXE->terminate

1 IEXPLORE.EXE->terminate

2 IEXPLORE.EXE->terminate

 

Similarly if you want to terminate all instances of IE on a remote system ‘machine01’, you could say:

D:\scr>wmi.pl @machine01 -name=iexplore.exe terminate()

Query = select * from Win32_Process where   name='iexplore.exe'

0 IEXPLORE.EXE->terminate

1 IEXPLORE.EXE->terminate

2 IEXPLORE.EXE->terminate

 

Here is another example.

wmi.pl @machine01 win32_operatingsystem reboot()

This will reboot the remote machine. Of course, your current logged on user needs admin permissions on the remote system for this to happen.

 

 

That’s it for now.

I haven’t finished shaking my head at the power of this API that has been ignored to obscurity, and my neck’s beginning to hurt. Try your own stuff and in the meanwhile I will be adding to the script.

 

There are some things I want to add to script, but haven’t done out of sheer laziness and the thought of getting back to Perl’s rather arcane syntax.

·         Support for impersonation

·         Support for regular expressions

·         Support for method calls with parameters

·         Support for display the CIM class definitions

 

Here is the Perl source (Those of you who have used WMI in some way will notice the consistency when you use the API across languages). How large did you expect the source to be? Since I am a Perl newbie, this code maybe substantially clunkier than what could be written by experienced hands.

 

use Win32;

use Win32::OLE qw (in);

 

$system = ".";

$classname = "Win32_Process";

@props = ("name");

%prop_value=();

$namespace = "root/cimv2";

$call = "instances";

$serial_no = 1;

 

sub list_instances {

       $serv = Win32::OLE->GetObject("winmgmts://$system/$namespace");

       $objs = $serv->InstancesOf("$classname");

       $i = 1;

       foreach $obj (in($objs)) {

              if($serial_no == 1){

                     $str = "$i ";

              }

              else {

                     $str = "";

              }

              if ($all_props) {

                     foreach $prop (in($obj->{Properties_})) {

                           $str = "$str\n $prop->{name} = $obj->{$prop->{name}}";

                     }

                     $str = "$str\n"

              }

              else{

                     foreach $prop (in(@props)) {

                           $str = "$str\t$obj->{$prop}";

                     }

              }

              $str = "$str\n";

              print $str;

              $i = $i + 1;

       }

}

 

sub list_classinfo {

       $obj = Win32::OLE->GetObject("winmgmts://$system/$namespace:$classname");

       print "$classname Properties : -----------------------------\n";

       $i = 1;

       foreach $prop (in($obj->{Properties_})) {

              print "$i\t$prop->{name}\n";

              $i = $i + 1;

       }

       print "$classname Methods : -----------------------------\n";

       $i = 1;

       foreach $m (in($obj->{Methods_})) {

              print "$i\t$m->{name}\n";

              $i = $i + 1;

       }

}

 

sub list_namespaceinfo {

       $serv = Win32::OLE->GetObject("winmgmts://$system/$namespace");

       print "$namespace Classes : -----------------------------\n";

       $i = 1;

       foreach $class (in($serv->SubClassesOf())) {

              $path = $class->{Path_}->{Path};

              print "$i\t$path\n";

              $i = $i + 1;

       }

       print "$classname Namespaces : -----------------------------\n";

       $i = 1;

       foreach $ns (in($serv->InstancesOf("__NAMESPACE"))) {

              print "$i\t$ns->{name}\n";

              $i = $i + 1;

       }

}

 

 

sub call_method {

       $serv = Win32::OLE->GetObject("winmgmts://$system/$namespace");

      

       if ((scalar keys (%prop_value)) == 0){

              $query="select * from $classname";

       } else{

              $query="select * from $classname where ";

              $and = "";

              for $key (keys %prop_value) {

                     $value = %prop_value->{$key};

                     $query = "$query $and $key=\'$value\'";

                     $and = "and";

              }

       }

      

       print "Query = $query\n";

       $objs = $serv->ExecQuery($query);

       $i = 0;

       foreach $obj (in ($objs)) {

              print "$i $obj->{name}->$methodname\n";

              $obj->{$methodname};

              $i = $i + 1

       }

}

 

 

 

foreach $arg (in(@ARGV)) {

       if ($arg =~ m#/sys:(.*)#) {

              $system = $1;

       } elsif ($arg =~ m#@(.*)#) {

              $system = $1;

       } elsif ($arg =~ m#\/class\:(.*)#) {

              $classname = $1;

       } elsif ($arg =~ m#\-\*#) {

              $all_props = 1;

       } elsif ($arg =~ m#\-(.*)=(.*)#) {

              %prop_value->{$1}=$2;

       } elsif ($arg =~ m#\-(.*)#) {

              @props[$#props+1]=$1;

       } elsif ($arg =~ m#^\?$#) {

              $call = "classinfo";

       } elsif ($arg =~ m#dir#) {

              $call = "dir";

       } elsif ($arg =~ m#(.*)\(.*\)#) {

              $methodname = $1;

              $call = "method";

       } elsif ($arg =~ m#\/ns\:(.*)#) {

              $namespace = $1;

       } elsif ($arg eq "/no_serial") {

              $serial_no = 0;

       } elsif (($arg eq "help") || ($arg eq '/?')) {

              print "WMI command line Tool (c)Roshan James, 2004\n\n";

              print "Help is available at:\n";

              print "http://www.thinkingms.com/pensieve/CommentView,guid,64df1ee9-a582-474c-960a-0063cd848609.aspx\n";

              print "Or mail spark\@mvps.org\n\n";

              exit 0

       } else {

              $classname = $arg;

       }

}

 

if ($call eq "instances") {

       list_instances();

} elsif ($call eq "dir") {

       list_namespaceinfo();

} elsif ($call eq "classinfo") {

       list_classinfo();

} elsif ($call eq "method") {

       call_method();

}

 

Saturday, May 01, 2004 1:55:11 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Friday, April 30, 2004

Marcello Tosatti

The current maintainer of the Linux kernel.

http://kerneltrap.org/node/view/1880/5842

Marcelo Tosatti became the maintainer of the 2.4 stable kernel when he was 18 years old in November of 2001. His first kernel release was 2.4.16 on November 26'th which very quickly followed the earlier 2.4.15 to address an issue with filesystem corruption. Two years later, he has recently released 2.4.23 and plans to soon put the 2.4 stable kernel into maintenance mode, only addressing bugs and security issues.

Well, if you can handle a wife at age of 20, the kernel is nothing ;)

 

Yukihiro Matsumoto (Matz)

The author of the Ruby programming language.

http://www.artima.com/intv/craftP.html

Yukihiro Matsumoto, the creator of the Ruby language, talks with Bill Venners about becoming a better programmer through reading code, learning languages, focusing on fundamentals, being lazy, and considering interfaces.

Bill Venners: You also mentioned in your ten top tips: "Be lazy. Machines should serve human beings. Often programmers serve machines unconsciously. Let machines serve you. Do everything you can to allow yourself to be lazy." Why should I try to be lazy?

Yukihiro Matsumoto: You want to be lazy. You want to do anything to reduce your work. I work hard to reduce my work, to be lazy.

 

Miguel De Icaza

Coauthor of Mono, Gnome, MC.

http://msdn.microsoft.com/netframework/using/understanding/cli/default.aspx?pull=/library/en-us/dndotnet/html/deicazainterview.asp

Using the ECMA Standards: An Interview with Miguel de Icaza

In this interview, Miguel de Icaza, the founder of GNOME and Ximian, talks about UNIX components, Bonobo, Mono, and Microsoft .NET

 

Charles Simonyi

Microsoft Distinguished Engineer – the WYSIWYG, Hungarian Notation, Intentional Programming

http://www.edge.org/digerati/simonyi/simonyi_p2.html

"Intentional Programming"

A Talk With Charles Simonyi

("The WYSIWYG")

 

Chris Pratley’s blog

Now here is man.

Chris Pratley is Group Program Manager with Microsoft’s Authoring Services – Word, Publisher OneNote.. Recently he has had a sent of blog articles about Word that you simply got to read. Absolutely got to read them because he says it – and he says it so in-your-face.

Let's talk about Word (168 comments) - look at the number of comments on this – this is at the time when I am writing this

Word Myths and Feedback (38 comments)

More Word Feedback (25 comments)

More responses to comments on Word posts (18 comments)

(Thanks Sajith for pointing me at this)

 

Friday, April 30, 2004 11:49:22 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Thursday, April 29, 2004

I thought of putting together some of my old mails and user group posting as blog entries, with some patches so that they are’ blogopatible’. They would have ended up on my blog, if I had a blog when I made these posts. I feel some of these are of lasting importance, at least with respect to the impressions they had on me.

 

All of these are personal opinions, probably more relevant in the context that they were originally written.

 

-----Original Message-----
From: James, Roshan
Sent:
Tuesday, December 09, 2003
11:57 PM
 Subject: XAML and markups: Introducing WFML - WinForms Markup Language

Hi Folk,

 

Ever since Linux Bangalore I have been thinking about something that Miguel de Icaza had demoed on stage. He was showing Mono’s UI, Glade, and showed how Glade generates UI from XML markup. They (Miguel and Nat) were also joking as to how XAML is an idea that they had thought of 6 years back – the idea of using XML markup for representing UI and separating 'business logic' from UI.

 

            He also went on to show how Glade is used to generate GTK# UI in linux. A '.glade' file is simply an xml file that contains tags that correspond to the properties of the controls (or widgets as they call them).

 

(I pulled glade file off the net to give you an idea of what it looks like

 

< widget class="GtkWindow" id="window2">

  < property name="visible">True< /property>

  < property name="title" translatable="yes">window2< /property>

  < property name="type">GTK_WINDOW_TOPLEVEL< /property>

  < property name="window_position">GTK_WIN_POS_NONE< /property>

  < property name="modal">False< /property>

  < property name="resizable">True< /property>

  < property name="destroy_with_parent">False< /property>

 

  < child>

    < widget class="GtkButton" id="button1">

      < property name="border_width">10< /property>

      < property name="visible">True< /property>

      < property name="can_focus">True< /property>

      < property name="label" translatable="yes">button1< /property>

      < property name="use_underline">True

      < property name="relief">GTK_RELIEF_NORMAL< /property>

    < /widget>

  < /child>

< /widget>

 

)

 

The strange thing was how they used glade files - in XAML you compile the xml file to generate a class (or what MS calls a partial class, one that can be extended elsewhere). In glade they did no such thing, they simple wrote a cs file and called one Glade API function passing it the name of '.glade' file. That returned some kind of object and presto they had their UI. Now the claim was that this really separates the UI from the code and as a matter of fact the XML can be chnaged after the exe file has been compiled. Changes to the XML will reflect in the UI without recompilation of anything. They also mentioned that Microsoft hasn’t figured out how to do this yet.

 

(Here is fragment of c# code that uses the .glade

 

                using Gtk;

                using Gnome;

                using Glade;

                using GtkSharp;

 

        public class GladeTest

                {

                                /* If you want to access the glade objects you have to "import" them.

                                 * This is not required, but else you can only work with the

                                 * pre-defined signal handlers */

                                [Glade.Widget]     

                                Button button1;

 

                                public GladeTest (string[] args)

                                {

                                                Application.Init();

 

                                                /* This loads the glade file glade.glade,

                                                 * selects window2 and connects it to the current object,

                                                 * which is the class GladeTest here. */

                                                Glade.XML gxml = new Glade.XML ("file.glade", "window2", null);

                                                gxml.Autoconnect (this);

 

                                                button1.BorderWidth=10;

 

                                                Application.Run();

                                }

)

 

            Now this got me thinking about how they implemented this dynamic behavior - as result of which WFML was born. It was rather surprising how easy this was to do. I am sure Miggy's code will be better and more optimized, but I think my general direction is correct.

 

WFML, in short provides (or at least hopes to provide) a markup language for UI that simply does not have to compiled (in the conventional sense). WFML UI is actually WinForms based UI, WFML by itself cannot add any features that are not present in WinForms. What it does is that it lets you write very clean looking code that does not have a clutter for UI itself. The entire UI of the program is expressed in an external XML file, called a .wfml file. Now if you have ever tried writing a Win forms application by hand without studio, you will remember how hard it is to remember so many of the house-keeping things required - take a look at some WFML based code:

 

//win.cs

using System;

using System.Windows.Forms;

using System.Windows.Forms.Markup;

 

 

class CMain

{

        static void Main()

        {

                IAttachable win = new Wfml().CreateUserInterface("win.wfml","MainWindow");

                Application.Run((Form)win);

        }

}

 

Simple ? This is a C# file that uses the WFML library. The markup lib being a pure .Net assembly can be used by any .Net language, - C#, VB, C++, Jscript, VJ# etc. Now what you need is a WFML file that specifies the UI. And you simply write the .wfml file like this (win.wfml):

 

 

        < Window

                Name="MainWindow"

                Height="200"

                Width="400"

        />

 

As you can see, the WFML is simply an XML file with certain tags that the WFML library understands. The advantage of using something like WFML is that you can completely change this XML at will and the UI of your program can be completely changed.

 

Now compile the cs:

   

csc /t:winexe /r:System.Windows.Forms.Markup.dll win.cs

 

Run win.exe and you will see an empty window

 

The following .wfml code displays a button and a text box for the same win.exe program. The program need not be edited or recompiled, only the .wfml file needs to be changed.

 

< Window

        Name="MainWindow"

        Height="200"

        Width="400"

       

        Text="Main Window"

>

        < Button Name="mybutton"

                Top="10"

                Text="Click Me"

        />

        < TextBox

                Name="tbox"

                Top="40"

                Left="5"

                Width="200"

        />

 

(What tags and attributes are allowed within a WFML? Every attribute that you set in a tag has to be a property of the corresponding WinForms type. That is to say that if you want to put a attribute called ‘Text’ in the ‘Window’ tag, then the class System.Windows.Form.Window should support a property called Text. WFML being a very simple system is case sensitive and provides no error feedback if something is wrong.)

 

And you can even attach event handlers and write back to the UI:

 

using System.Windows.Forms;

using System.Windows.Forms.Markup;

using System;

 

class CMain

{

        public TextBox tbox;

         

        public void clicked(object sender, EventArgs e)

        {

                tbox.Text+="+ ";

        }

        

        static void Main()

        {

                IAttachable win = new Wfml().CreateUserInterface("win.wfml","MainWindow");

                CMain cm = new CMain();

                win.AttachConsumer(cm);

               

                Application.Run((Form)win);

        }

}

 

Do try some WFML, the supported types are Button, TextBox and Label - but I guess the rest can be added easily.  Now I don't think this was anywhere as hard as they were making it out to be on stage.

 

Roshan James

------------------------------

 

 

You can download the WFML.zip file here. This also contains the demos that I had for this UG post.  While I never did continue on the WFML, folk did mail me back asking about the WFML assuming it was part of a larger UI framework.

 

Of course, capital negatives of the approach are that there is no IDE to ease development of WFML and such, but the idea itself is rather interesting.

 

How WFML actually works, as you might have guess is that it uses reflection API to dynamically generate a System.Windows.Form type that is customized according to the WFML file. This runtime generated type also runs reflection based code on its caller and appropriately latches up event handlers dynamically. Also it uses reflection to assign references of the caller to classes to the actual objects created in the generated Form class.

 

You however need not compare XAML to WFML or like approaches because XAML is a whole different beast. Differences start with be67ing vectored based don’t stop any time soon.

Thursday, April 29, 2004 5:49:08 AM (Eastern Standard Time, UTC-05:00)  #    Comments [1]  | 
 Tuesday, April 27, 2004

I thought of putting together some of my old mails and user group posting as blog entries, with some patches so that they are’ blogopatible’. They would have ended up on my blog, if I had a blog when I made these posts. I feel some of these are of lasting importance, at least with respect to the impressions they had on me.

 

All of these are personal opinions, probably more relevant in the context that they were originally written.

 

-----Original Message-----

From: James, Roshan

Sent: Friday, December 05, 2003 5:37 PM

To: MVP Mailing List

Subject: An Audience with Miguel

 

 

written in a hurry:

 

An Audience with Miguel

 

Hi, yesterday Pooja and I got to catch a part of Linux Bangalore, the annual Linux convention, and I thought that it would be nice to write to mvplist and share our experiences. We had missed the dates for the event and I was rather shocked at having missed a chance to see Miguel De Icaza in person.

 

Miguel, for those who don't know about him, is the creator of mc (the Midnight commander), Gnome (the rather popular open source desktop) and in recent days the lead for the Mono project. The Mono project is the only other major (when I say major here, it is not that I don’t know of dotGNU and other attempts, it is because I personally feel that Mono is more complete than those) .Net implementation outside of the Microsoft world. Mono runs on Windows as well as on Linux and probably other Unix flavors. This guy has been famous/notorious in the open source community for writing papers like 'Lets make Unix not suck' and has a rather 'misfit' personality for the typical religious ramblings of the free software types. In short this man has written his own windowing systems, his own .Net, his own enterprise servers and was running his own company called Ximian.

 

Ximian has been recently bought by Novell making Novell a major player in the open source world. Novell has also bought Suse - major Linux flavour and Novell seems to be on the path of becoming a significantly important open source company, along the lines of maybe Red Hat and such. However unlike Redhat and many of the 'Linux companies', Novell has a focus on delivering products rather than making Linux distributions and delivering them dirt cheap or free if they have to, to get into the market. So in short Miguel is as much a demi-god as our own Anders Hejlsberg, or Don Box.

 

The above paragraph was to set things in perspective. This is the mono website (http://www.go-mono.com/). Having been rather disappointed to have missed Linux Bangalore dates and missed Miguel, I happened to check their talk schedules by sheer accident around 11.30 yesterday. As fate would have it, there was a talk by Miguel, his last one, scheduled at 12.00. After a ~12km drive and some conversation with the registration counter we were at the IISC Bangalore venue – the last time I was here, I was attending the Microsoft Tech Ed.

 

One thing you notice up front as you enter is a big banner of Abdul Kalam, our president. The poster quotes him saying that it is probably not good to have important national software depending on proprietary solutions as proprietary solutions and highly dependant on the market that the vendors cater to and that sort of unreliability is probably not a good thing. And also that free software would really help a poorer country like ours as prices of commercial software are rather high. At least that was the message in spirit - don't think I have got any of his words right.

 

The crowd, as far as I could say was probably the same caliber as the technical crowd I usually get to interact with at UGs and various .Net technology events. Probably not as good in some respects - but there was this thing in the air that they were all up to 'something important'. Also one other thing that was noticeable was the set of demo computers setup, where people could sit down and try out many of the software that was being talked about in the talks.

 

Miguel's talk was at the main hall of the IISC venue (those who know the place will know what I mean). He was accompanied by Nat Friedman of Novell, a fellow mono-ist. What happened at the talk was something I wasn't prepared for. For those of you who have a mental image of Miguel by now, this guy is young, in his early twenties. He was carrying a digital SLR camera with a hefty lens and flash addons and was dressed in baggy jeans and black t-shirt. So was the other guy Nat. Now these guys hop on stage (literally), sit down on the floor - one of them rolls out a length of cable that he had wrapped around his neck the whole while. They pull out two laptops and they get a network setup between their systems and the presentation starts up.

 

The presentation showed of some parts of C# , web services, GTK# for windowing, GTK + for generating XML markup for the UI (and some jokes about how XAML is a copy of their own 6 year old idea) and more. These guys did the whole presentation sitting or lying down on the floor of the stage, sometimes editing the presentation right there in front of the audience, pulling jokes on each other and writing code the whole time for a full hour - and the whole thing was on their own Mono. Awesome.

 

After the talk Pooja and I met up with Miguel and introduced ourselves as being from the ‘dark side’ (He asked me if I was an ASP.Net developer because of all the questions I was asking from what otherwise seemed to be a relatively .Net ignorant audience. He was interested in the fact that I was an MVP.) and asked him if we could meet him sometime later, maybe over dinner or so. He was fine with that – that however was not to happen as his schedule did not allow him to. Various activities were planned for him for the whole of the next day (today, Friday) and he was going to flying on Saturday. He did promise to talk to our .Net user group the next time he is in India (expected to be in the second quarter of next year). I had to get back to office so I had to leave then; with the intention of returning for Jani's talk a little later in the evening.

 

I managed to sneak out of office again to attend the talk by Mr. Janakiram (I hope you know him - he heads Microsoft India's academic/university relationship program). Along with Jani was Mr. Gaurav Daga (he is a Program Manager of the famous Services for Unix team at Hyderabad; SFU won last years best open source software of the year award). Their venue didn't do any justice to their talk. Their talk was scheduled at one of the smaller halls and the crowd was so packed for the talk that I couldn't get close to the door of the hall. Jani and Gaurav as usual pulled a great show. They were talking about the new 'Unix' being built in windows ;) (Their demo was rather awesome: they took a Unix app ran it on windows literally, they wrote .Net code and exposed it as a web service, they built a proxy around the service and consumed the proxy as a COM component which was used by excel which was used to dump – did I miss anything?)  

 

All the while, from when he finished his talk, Miguel and his gang were there in the main lobby, showing off code or sitting or taking photographs or ready to talk to anyone at all about anything. When he was not doing that he would be sitting around in some corner with Nat typically typing away at a piece of code he was working on.

 

Since I couldn't get to listen to Jani at all due to the crowd and having driven the ~12km stretch in Bangalore traffic for the third time that day, I was walking around looking rather moody. Miguel then walks up to me, 'Microsoft dude', and gets our picture taken together. He kept calling me 'Microsoft dude' and he himself wanted to be called 'The Dude'; it was interesting talking to him.

 

I wanted to introduce Jani and Gaurav to Miguel and Nat after their talk. It was funny because on meeting Jani and Gaurav, Miguel seemed to freeze up a little bit - I think it's that Microsoft-effect. But on the whole they were nice folk. And Jani and Gaurav were good too. Jani mentioned how he wrote a wrapper around the 'Tk' widget library and called it a windows forms assembly and got to run some regular winforms code on Linux’

 

In retrospect, if I wanted to pick faults with the event I could and I could say that the organizing was bad, because the projector was shaky and the stage wasn't setup properly and the food was bad and all that and be complacent about the whole thing. But looking at the good side, you see guys who are probably the gods of their community actually sitting around with the developers showing off their code and laughing and talking rather that running off after a talk or sitting in a separate area. These are probably something's that we could learn from these folk. The number of people who Miguel touched that day and the number of people who will remember him are much more that those who will remember any of the speakers at technology forums where I have had the opportunity to speak or attend.

 

Miguel was different from my vision of the open source advocate. Probably because he was less of an advocate and more of a real programmer.

 

Miguel said that no they don't say that they are going to beat Microsoft or that Microsoft is going away or anything - which is normally common talk for OSI folk I have previously met. There is place for both he said. He said he has friends at Microsoft. He said that Dave Stutz is a good friend. We talked a little about Stallman and Free software. I asked him if he would be joining MS like Don Box offered and he said probably not. He would rather be doing his thing like this and be 'helping out the poorer countries'. He says they will keep on writing software, take good ideas wherever they find them and give it out as dirt cheap or free. There was this time when he said that 'they took out the GC and put in a toy GC in rotor and took out the JIT and put in a toy JIT in rotor - but the GC in Mono is your GC as much as its my GC' and he said that to Jani - 'its your as much as its mine and I would like to keep doing that'. There is this certain element of real sincerity which I find so missing in my work place and often at our technical seminars.

 

Free wheeling aside and sorry for all the typos and bad language in my writing, one thing that I probably miss from speakers and from many of our communities is that people hardly seem to be doing all that for themselves as much as for the community - I haven't seen anyone sit down and give all their time and energy to the community they are trying to foster. I don't see anyone on our side actually be there with the people and spread that sense of what they are doing - most of the audiences at our talks see us as speakers on podiums, rarely as people, we don't usually give them the room for that. I wish we could do that. And I wish that when we work on our user groups we can do it for the sense of community, rather than for the sakes of meeting numbers and budgets and revenue targets and stuff. I wish we all do this because we like our technology first - the Microsoft communities have never been able to do that the way these guys have. (This was probably rant, but reading this months later I feel that a lot of human touch is still missing in the communities. Somewhere the communities are built around a carrot culture and people who do things for carrots. Miguel has his carrots, but the way I saw his carrots were from a kind of passion that I personally feel in speakers I have known, myself being equally at fault. Something about what happened there that day felt like the spirit of those things I have thought about so much – hackerdom, the free hackers, the hacker ethic, mentor’s manifesto. Something is missing here and I am sure we can fix it because we have some extremely smart people who are so passionate about their technology)

 

I hope I have not tipped off any one by writing all this; this is probably something that could use some thought.

 

Cheers

Roshan

 

(Left to Right: Natt Friedman (Ximian/Novell of the Mono Project, cofounder of Ximian), Me, Miguel De Icaza (Ximian/Novell - author of Mono and other great feats of hackerdom, cofounder of Ximian), Gaurav Daga (Program Manager, Microsoft - Services for Unix Team), Pooja Malpani (CTS - programmer, Microsoft MVP .Net). This was taken at Linux Bangalore 2004, the annual Linux convention.)

 

 

(President’s quote put upon a hoarding at Linux Bangalore 2004)

 

 

 

This was recently posted on Miguel’s blog (there is more - go read the entry):
http://primates.ximian.com/~miguel/archive/2004/Apr-24.html

 

Jeff seems to like Cringley's statement of "The central point was that paying too much attention to Microsoft simply allows Microsoft to define the game. And when Microsoft gets to define the game, they ALWAYS win."

 

A nice statement, but nothing more than a nice statement, other than that, its all incorrect.

 

Microsoft has won in the past due to many factors, and none of them related to `Let them define the game', a couple from a list of many:

 

·         They leveraged their monopoly to break into new markets. The most discussed one is when they used brute force and anti-competitive strategies to get their products into new markets, but in some other cases they got fairly good adoption of their products with little or no effort: just bundle it with Windows: MSN messenger, Media Player.

 

·         Competitors were outmaneuvered or were incompetent (See HIgh Stakes No Prisoners).

 

·         People were sleeping at the wheel.

In 1993-1994, Linux had the promise of becoming the best desktop system. We had real multi-tasking, real 32-bit OS. Client and Server in the same system: Linux could be used as a server (file sharing, web serving), we could run DOS applications with dosemu. We had X11: could run applications remotely on a large server, and display on small machine. Linux quickly became a vibrant innovative community, and with virtual-desktops in our window managers, we could do things ten times as fast as Windows users!
TeX
was of course `much better than Windows, since it focuses on the content and the logical layout' and for those who did not like that, there was always the "Andrew" word processor. Tcl/Tk was as good as building apps with QuickBasic.

And then Microsoft released Windows 95.

 

·         A few years later, everyone is talking components: Netscape is putting IIOP on their client and server (ahead of their time, this later became popular as web-services on the browser); Xerox ILU; Bonobo; KParts; the Borland sponsored event to build a small component system that everyone agrees with; language bindings are at their top.

The concensus at that time? Whatever Microsoft is doing is just a thin layer on top of COM/DCOM/Windows DNA which to most of us means `same old, same old, we are innovating!'.

And then Microsoft comes up with .NET.

 

 

Maybe, sometimes, rarely, one man can change the world – or at least make a significant dent.

 

Tuesday, April 27, 2004 1:04:00 PM (Eastern Standard Time, UTC-05:00)  #    Comments [4]  | 
 Sunday, April 25, 2004

Iterators in Ruby (Part - 1)

Warming up to using Iterators (Part 2)
< I am yet to write a part 3 >
SICP, Fiber api and ITERATORS ! (Part 4)

 

I had a look at the implementation of iterators in C#. What follows is based on code generator I have seen on the C# Whidbey post PDC release. Things might have changed by now as things are moving to technology preview phase.

 

This is example code that is present in MSDN:

 

// yield-example.cs

using System;

using System.Collections;

public class List

{

    public static IEnumerable Power(int number, int exponent)

    {

        int counter =0;

        int result = 1;

        while(counter++ < exponent)

        {

            result = result * number;

            yield result;

        }

    }

 

    static void Main()

    {

        // Display powers of 2 up to the exponent 8:

        foreach(int i in Power(2, 8))

            Console.Write("{0} ", i);

    }

}

 

Notice the introduction of a nice little ‘yield’ keyword? The behavior of C# iterators in this context is a lot like ruby iterators that I have been talking about in previous articles. Knowing a little about the state management requirements for iterators and the fact that the CLR is stack based, how are iterators implemented in C#?

 

The implementation of iterators in C# is not driven by the CLR in any way, it is completely implemented in the language as a compiler construct.

 

Let me explain what the compiler tries to do – the compiler examines the function that does the yield

 

    public static IEnumerable Power(int number, int exponent)

    {

        int counter =0;

        int result = 1;

        while(counter++ < exponent)

        {

            result = result * number;

            yield result;

        }

    }

 

Lets just ignore the yield statement for now and look at the method as thought it contained only a loop. It would basically look like this:

 

    public static IEnumerable Power(int number, int exponent)

    {

        [initial code]

        while([loop condition])

        {

            [loop body]

        }

        [post loop code]

    }

 

This is then generated into a sequence of IL statement blocks that have the following jumps between them:

 

 

Now, what yield would require is that the method exit at each point a yield statement occurs. The next time the method is invoked, execution continues immediately past the yield statement with all variables preserving their values.

 

In the CLR, when a method returns its stack frame is torn down. So there is no way that the local variables can actually preserve state. The solution taken by the C# team is turn the method that implements the yield statement into a class.

 

Such a class would

 

·         Have all local variables of the method as members of the class

·         Have a special variable that hold the value that is being yielded.

·         Have a special variable to indicate where the method should continue from, the next time it is invoked.

 

When the caller of such a method runs and encounters the foreach loop that invokes the iterator an object of this class gets created. This object is maintained as long as the foreach lop is running. When the loop exits the object is disposed.

 

That’s how iterators are implemented in C#. :)

 

Now here are some details:

 

 

The method that implements the iterators generates not one but two classes. Both the classes are generated as nested/inner classes to the class that contains the method. The classes are named as
(method name)$(number )_IEnumerableImpl
(method name)$(number)_IEnumeratorImpl

 

I am not sure about the exact reasoning behind the generation of two classes. The earlier standard for writing enumerators in C# probably required, but from the standpoint of implementing iterators, I don’t understand the need.

 

The first of these, the IEnumerableImpl simply creates an instance of the second class and returns it to the caller.

 

The second class IEnumeratorImpl is the interesting one. This class has data members for all the local variables as well as our two special data members.

 

Compare the data members (the cyan colored diamond shapes) to the original  local variables of the method.

 

    public static IEnumerable Power(int number, int exponent)

    {

        int counter =0;

        int result = 1;

        while(counter++ < exponent)

        {

            result = result * number;

            yield result;

        }

    }

 

The parameters number and exponent are there as such and the local variables counter and result are there with some name mangling (I would expect this is to avoid clashes with duplicate names in nested scopes, though that is not allowed in C# (duh?)).

 

The two new members on the class are

·         $PC

·         $_current

 

$_current is the member that holds the yielded value. In the case of the above method, $_current holds the value of ‘result’. It is an ‘object’ type for there will be a nice boxing and gc overhead when moving around an int type – I don’t know why something was not done for special casing value types.

 

$PC is the interesting variable. Remember our little diagram above that showed execution through IL. In the case of the iterators, the method does not simply execute in a loop like shown there, but executes one iteration of the loop on each call. The $PC is the variable that keeps track of where the code should jump to, the next time the method is called. Understandably $PC is someone idea of program counter ;)

 

The code method called MoveNext() in the class actually does the work that the method power() originally did. This is what is look like in IL code.

 

 

Sorry I am not very good with diagrams, but if you look at it you will see that the code is simply built for repeated invocation. Each time according to $PC the code braches to a new location and executes. It then sets the value of $PC to a new location of entry before the function exits.

 

In C# the yielded value is assigned to the $_current member variable and the MoveNext() itself exits by returning a true or false. A true indicates that the method returned through a yield and the false indicates that the method has completed execution. Subsequent calls to the method, after it has returned false will simply cause the method to return false and the $_current will not be updated.

 

So how does the caller of an iterative method behave? In this case its the main. The  caller simply does the following –

 

Invoke Power$00000000__IEnumerableImpl. GetEnumerator() to get an instance of Power$00000000__IEnumeratorImpl

 

Invoke Power$00000000__IEnumeratorImpl.MoveNext()

 

If result is true, use invoke Power$00000000__IEnumeratorImpl.get_Current() which will return the $_current. The foreach loop will cause the MoveNext() to be invoked again after the reurned value is consumed.

 

If result is false, break out of foreach loop.

 

After the loop breaks out the instance of Power$00000000__IEnumeratorImpl is dispose and is available for garbage collection. 

 

I am looking forward to the beta preview to see f things have changed. There is a lot of rather redundant code generated by the compiler here that I have not mentioned. When you are reading IL you might want to skip over those parts.

 

Probably in the future the CLR will contain constructs that enable true iterators and closures. Present day processors don’t natively support such constructs and so implementation will have to be hacks on the C stack or using some kind of class-object mechanism like shown here.

 

As a foot note I would like to mention that the Python also implements iterators in a manner similar to C#. There the function that yields is also converted into a class that maintains state. I believe the MoveNext() equivalent in Python is simply next(). Python however raises an exception to signal end of iteration. C# uses a Boolean return value to indicate this.

 

If this topic holds your interest then I recommend reading:

 

Coroutines in C
by Simon Tatham

 

C# 2.0 Create Elegant Code with Anonymous Methods, Iterators, and Partial Classes
by Juval Lowy (MSDN Mag)

 

Charming Python: Iterators and simple generators - New constructs in Python 2.2
by David Mertz (developerWorks)

Sunday, April 25, 2004 6:16:33 AM (Eastern Standard Time, UTC-05:00)  #    Comments [9]  | 
 Friday, April 23, 2004

There is Dylan playing somewhere in my head, and some things feel crushed:

 

Though I know that evenin's empire has returned into sand,

Vanished from my hand,

Left me blindly here to stand but still not sleeping.

My weariness amazes me, I'm branded on my feet,

I have no one to meet

And the ancient empty street's too dead for dreaming.

(Tambourine Man)

 

Have you ever listened to Dylan? Actually heard the visions of what could have been move by you? Probably not, not many people like to listen.

 

Then take me disappearin' through the smoke rings of my mind,

Down the foggy ruins of time, far past the frozen leaves,

The haunted, frightened trees, out to the windy beach,

Far from the twisted reach of crazy sorrow.

Yes, to dance beneath the diamond sky with one hand waving free,

Silhouetted by the sea, circled by the circus sands,

With all memory and fate driven deep beneath the waves,

Let me forget about today until tomorrow.

 

Hey! Mr. Tambourine Man, play a song for me,

I'm not sleepy and there is no place I'm going to.

Hey! Mr. Tambourine Man, play a song for me,

In the jingle jangle morning I'll come followin' you.

 

Sometimes, the closed world of the bit and baud seems to be the only reality that matters and somewhere it cajoles you into believing in a certain brotherhood of those who seem to understand it. And then again sometimes not.

 

And do you listen to Simon and Garfunkel?

 

When you're down and out, When you're on the street
When evening falls so hard, I will comfort you
I'll take your part, when darkness comes
and pain is all around,
Like a bridge over troubled water, I will lay me down
Like a bridge over troubled water, I will lay me down

(Bridge over Troubled Waters)

Friday, April 23, 2004 2:17:13 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Thursday, April 22, 2004

I downloaded and tried the new programming language Groovy today. In short groovy is like having Ruby on JVM. Maybe only better, because, it now has the power of the whole JVM to leverage. This is the homepage:

http://groovy.codehaus.org

 

 

The language is a stunner.

 

There is a lot of neat language design going on here.

http://wiki.codehaus.org/groovy/BlocksAndClosures

Imagine something like Ruby actually being available to code JSP, beans and what not in the Java world.

 

Being from the .Net background, I wish this was being done for the CLR. Imagine the power to the multi language support of the CLR brought into something like Ruby. For now I am content with gaping at features like this:

 

def counter(a)

{

      c = a;

      x = {c +=1; c};

      x

}

 

a_counter = counter(0)

b_counter = counter(20)

 

println(a_counter())

println(b_counter())

println(a_counter())

println(a_counter())

println(b_counter())

 

This actually works. Real closures!
If you are a lost C or VB soul, what is happening is that the function/method called counter() creates and returns a closure called x. A closure is a block of code that maintains state and scope based access to its variables. So closure x has the maintains state and has access to the variables of the method counter().

a_counter and b_counter are instance of the closure in the counter() method, that live after the invocations to the counter() method has exited. You can see that state is maintained between calls as the value of ‘c’ is incremented in each successive call.  

 

This is way ahead of languages like C# which are just grappling with their implementation of yield. This is of course not to blame the C# team, because admittedly the concept of programming with closures is yet to hit ‘the masses’

 

Groovy seems to do a whole pile of exciting things that Ruby can do

·         Closures

·         Iterators and Blocks

·         Regular expressions

·         Flexible collection types

·         Dynamic Method Invocations and types

I haven’t seen any mention of continuations, extendible classes, mixins and the like yet.

 

Of course, being on the JVM is slow and implementing a lot of features like the ones above, accounts for expensive constructs, which make the language even slower. However for most scripting language speeds, it should be acceptable.

 

What I think is more important is that languages of Ruby stature are being implemented on popular OO virtual machines. This is a sign for a possible trend in the future – a good one. It will be interesting times ahead when we have dynamic languages and functional languages move onto popular VMs.

 

I really like C and I think that simplicity is a feature (EricGu), however there is a real wealth of possibilities to be gleaned if constructs that have long been available only to students and researchers actually hit popular programming.

 

I am excited about the possibilities of a Ruby like implementation under .Net. Python is already getting there with Jim Hugunin and his IronPython.

 

Here are the folk behind Groovy:

http://groovy.codehaus.org/team-list.html

 

If you enjoy programming in Ruby or in a language that supports lists, iterators, closures etc, you might enjoy Groovy. It is still under development, so there might be things that are missing. You will also have to get the JVM.

 

Thursday, April 22, 2004 3:09:35 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Wednesday, April 21, 2004

This is a Wish List for Ruby. Ruby is an excellent language, however here are some small things that I would like to see added to Ruby:

 

  • Threading
    I wish ruby had real threads. The threading support currently provided is really sad. If Rite could actually have OS threads as Ruby threads, like in the .Net framework it would be awesome, instead of doing them as interpreter threads. Write now doing any sort of meaningful multithreaded application in ruby is meaningless.

  • C/C++ style operators
    I wish ruby had ++, -- operators. They really do not contribute to unmanageable code and on the whole are nice things to have.
  • Use of Curly Braces { }
    I wish that Ruby would let the usage of curly braces to define blocks of code other than just parameter blocks that receive yield results. I would like to use {} to enclose methods, classes, if statements, loops etc.

    Write now code that is written like:

    def func(a)
       [1,2,3].each {|n|
          if(n % 2 == 0)
             print “This is even”
           else
             print “Odd”
             print “Multiple of 3” if (n%3==0)
           end
       }
    end


    being very C-ish in my ways I would really like it if I could avoid all those clumsy ends.

    def func(a) {
      [1,2,3].each {|n|
        if(n%2 == 0)
          print “This is even”
         else {
             print “Odd”
             print “Multiple of 3” if (n%3==0)
         }
      }
    }

     
    These days since the Python bug has bitten a bit, I am warming up to the idea of scope by indentation.

    def func(a)
      [1,2,3].each |n|
        if(n%2 == 0)
          print “This is even”
         else
             print “Odd”
             print “Multiple of 3” if (n%3==0)

    This actually looks quiet nice, but it may not be a good think to have because such code often tends to get messed up real bad when you copy paste it around and spoils the indentation.


  • Better Win32Ole libraries
    This is something that I must have. I use scripting to be able to talk to WMI (Windows Management Instrumentation).

    The libraries that Ruby ship for this is really sad. Very unstable. At the time of this writing the current Ruby distribution has removed the win32ole libraries from Ruby. I hope they will come back, stabler.

    The reason why Win32Ole is important to me is that it is the mechanism used to talk to WMI and WMI can let you some really awesome stuff.

    WMI Primer on MSDN

  • Auto Initialization of variables
    When I write code like this

    sum = 0
    10.times{|n| sum = sum + n }


    I wish I need not have to initialize ‘sum’. I wish there was some unambiguous way of saying that ‘I know sum hasn’t been defined before, so please use its initial value as ’. I would just like to be able to say 10.times {|n| sum = sum + n } and things should just work, assuming that sum gets initialized as 0. I wish there was some shorthand hand initializing a variable for its first appearance in an expression.

    Like I could probably replace:

    sum  = 0
    prod = 1
    10.times {|n| sum = sum + n; prod = prod * n }

    with

    10.times {|n| sum = sum<0> + n; prod = prod<1> + n; }

    or better if I had support for C++ style operators, I could write

    10.times{|n| sum<0> += n; prod<1> *= n; }


  •  Run on .Net
    I wish ruby could run on .Net. There are python variants that run on Java and now Python is coming up for .Net (
    IronPython). Imagine the power of having the flexibility of Ruby with the power and expanse of the .Net framework.

    Maybe more work needs to be done before this is possible.

  •  Currying of Methods and Partial Evaluations
    I wish I could have currying/partial evaluation possible for ruby methods.
    In many functional languages, functions are defined like this:

    - fn add x y = x + y
    > int -> int -> int

    Consider the ML like code above. The first line I have defines a function called ‘add’ that takes x and y and does x+y. The second line is what the interpreter echoes back to me about the function.

    It is simply is trying to say that the method consumes two integers and produces an integer. The two integers how ever are not used up at one go, rather, they are used up sequentially. First the integer x is taken and bound to the function and then the value y.

    By being able to do that, we can define other function instances of add that have one of the variables bound.

    - fn add10 = add 10
    - fn add5 = add 5
    - add10 2
    > 12
    - add5 2
    > 7

    This shows off some very powerful features of what currying can do. Here add10 and add5 are created as new functions, but with the value of x substituted as 10 and 5 respectively. Now we can treat add10 and add5 as proper functions that take only one parameter. 


    What these languages let us do is that we can apply a subset of the parameters of a function and created a curried or partially evaluated function instance. Such an instance can, if the runtime is optimizing enough, already do all the processes possible in the code upfront. Whenever the remaining parameters are supplied, it could just go on to complete the operations.  

Imagine that the method we were calling is this

fn mult x y = 10 * x * y

and then we wish to do


mult 10 2

mult 10 3

mult 10 4

 

These calls will now cause it to do 10 * 10 * 2, 10 * 10 * 3 and 10 * 10 * 4

However if we could partially evaluate a function we could say

 

fn mult10 = mult 10
mult10 2

mult10 3

mult10 4

 

When mult10 is created it is already evaluated to being “100 * y”. So, subsequent calls would cause it to do only 100 * 2, 100 * 3 and 100 * 4.

 

To add this sort of support to Ruby will have to bring large changes to the language. A simpler implementation would be to create a method object (yes that’s possible in Ruby) and also a hash of the partial list of parameters. The call itself could be formally executed only when all formal parameters are satisfied by the parameter hash table collection.

 

If you are still reading this might interest you:

http://www.svendtofte.com/code/curried_javascript/

 

Whew!

Well, that’s about it for now. But as you can see most of what I am asking for here are simple things and superficial changes. I would however really like to see the win32ole, threads and ++ operators in Ruby, even if none of the others work out.

 

Matz, (Yukihiro Matsumoto), the creator of Ruby is planning to introduce some significant changes to the language and more importantly going to get it running off a formal virtual machine that he is writing for Ruby called Rite.

Here are some of the plans for Rite and Ruby:

http://www.rubygarden.org/ruby?Rite

 

I found this on one of the websites, this is about how Matz wanted to work on Rite:

 

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/76588
|* will Rite be developed publicly.. Or will you keep it souce secret?

From my experience and observation, an open source software needs to

have running code before the ball rolling to success.  I think I need to work alone until the first running version.

 

|* still use Ruby license scheme?

It will be open source software for sure.  License terms may be

changed.

 

|* do you need help?  Say what we should do and we will do it :-)

This is very important.  Listen carefully.

 

From the reason I stated above, I feel like I will work alone.

But if someone shows his talent, and comes up with his own _good_

implementation of new Ruby earlier than me, and if he is willing to

contribute his code, and if he allows me to hack and chop his code to

make it "Rite", I will name it "Rite".  And he will be honored for ever.

Wednesday, April 21, 2004 4:21:08 AM (Eastern Standard Time, UTC-05:00)  #    Comments [1]  |