Also included a demo console GUI : A GUI Application is also included that you can use to see for knowing how to interface your application to Cloak library.
Features:
Proposed Features for future releases
Download CloakDownload Cloak source
Usage:
string commands = "dir c: \n"
+ "del c:\bootscan.log";
ConsoleHelper CH = new ConsoleHelper();
string Results = CH.ExecuteCommands(commands);
string Errors = CH.LastError;
Know more about this project and follow it on Codeplex @ Cloak.CodePlex.com
]]>Not so easy dude… there are many hurdles:

So, let us assume somehow you get the page HTML within your page through plain Javascript/AJAX/jQuery or any other way, then how your page will get the data it wants…
Well, most of the pages has similar construct:
<doctype.... <html> <head> .. .. <script>..</script> . </head> <body ....> ... .. <<<<<Tags jungle>>>> .. <some sweet tag> <3 Your Data <3 </some tag> .. .<more tags> </body> </html>
What we will do is to load this page HTML into a javascript varible, then simply chop all the content section from the start up to tag, also trim any <script>
tags. Then we will run a wild replace using regular expression that will make any tag <* into <div tag
You can further continue this chopping and transformation of data to get closer to pure data. Once we have the HTML gone through the above process, we will have something that will look like this:
<div> <div> . . </div> <div> <div> <3 Your Data <3 </div> <div> .. .
which we will host(assign to innerHTML property) into an invisible div, which will force the browser to parse and render the HTML and make this HTML part of your DOM object.
Later you can query this data, using something like…
var data = docuemnt.getElementById("someId").innerText;
where someID is the parent element, containing required data.
Lets take an example of NewYork weather data page from AccuWeather.com:
URL: http://www.accuweather.com/us/ny/new-york/10017/city-weather-forecast.asp

if you inspect the page in IE developer tools, we will observe following:
now assuming that you have managed to load this HTML into your page JavaScript,and its assigned to the src variable, thus src should look something like this:

lets execute following JavaScript statements:
if(src === "")
return;
var i = src.indexOf(" src = src.substr(i); // chopped the Head part
tag = src.replace(/\<[a-z]+/gi,"
tag
alert(tag);
this should give us the output as shown below:

Further executing some more JavaScript statements provided below, we can reach to our data:
document.getElementById("host").innerHTML = tag;
data = $(".info").find(".cond").find(".temp")[0].innerText;
data = data.substr(0,3);
alert("Today's Temp: "+data);
// host here is a div element
document.getElementById("host").innerHTML = "Today's Temp: "+data+"°";
$("#host").show();
Result will give us the temperature.
Here is the full source code:
<html
<head>
<title>Page rip demo</title>
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.1.min.js"></script>
</head>
<body>
<script type="text/javascript" >
var url = "weather.htm";
var src = "";
onload = function()
{
$.ajax({'url':url,'success':function(source) {
{ src = source;
alert(src);
},
'error':function(r,s,x)
{
alert("Error while trying to get data
");
}});
}
function GetTemperature()
{
if(src === "")
return;
var i = src.indexOf("<body");
src = src.substr(i); // chopped the Head part
tag = src.replace(/\<[a-z]+/gi,"<div");
alert(tag);
document.getElementById("host").innerHTML = tag;
data = $(".info").find(".cond").find(".temp")[0].innerText;
data = data.substr(0,3);
alert("Today's Temp: "+data);
document.getElementById("host").innerHTML = "<h2>Today's Temp: "+data+"° C";
$("#host").show();
}
</script>
<input type="button" onclick="GetTemperature()" value="Show Temp">
<div id="host" style="display:none;"></div>
</body>
</html>
Which will give us the following result:

Pros: This approach is better than trying to parse the whole HTML yourself, which is more error prone and bound to fail frequently. Here we are letting the browser parse and include our HTML into the DOM, so we can run some simple JavaScript statements to get required data
Cons: this approach is way dirty itself and will fail someday, as soon as the page layout changes or somebody alters the source page HTML layout. Not to mention the browser compatibility as different browser treats things differently.
With the recent and continuing revolution going around on the web, things are getting easy with sites exposing their data through APIs or at least through Microdata/Microformats
]]>I had worked with this earlier, but this time I was not in the mood to do it again. I wanted something within the page itself as implementing a proxy will increase the complexity of the whole system. So, I did some “Search” and found this awesome solution that utilizes this neat approach of referencing script src to remote site. Basically, This means the page JavaScript has to dynamically create a <script> and set its source(src) attribute to the service URL, which in turn provide the data in JSON format that is natively supported in JavaScript. Thus, we will have our response data right inside our page in JSON.
Here is a possible implementation:
function JSONData()
{
this.serviceURL = "http://somesite.com/services/json.php";
this.scriptEle;
this.IdName = "script_id00";
this.getData = function()
{
this.scriptEle = document.createElement("script");
var oType = document.createAttribute("type");
var oSrc = document.createAttribute("src");
var oId = document.createAttribute("id");
oType.nodeValue = "text/javascript";
oSrc.nodeValue = this.serviceURL;
oId.nodeValue = this.IdName;
this.scriptEle.setAttributeNode(oType);
this.scriptEle.setAttributeNode(oSrc);
this.scriptEle.setAttributeNode(oId);
this.scriptEle.src = this.serviceURL;
document.body.appendChild(this.scriptEle);
}
// Use this function to reload/refresh the JSON data from the server
this.reload= function()
{
this.scriptEle = document.getElementById(this.IdName);
document.body.removeChild(this.scriptEle);
this.getData();
}
}
var jsonData = new JSONData();
jsonData.getData();
//change this delay according to your requirements
var delay = 10000; // let the JSON data arrive from the server
setTimeout("ShowData()",delay); //wait and let the JSON data arrive and get parsed
function ShowData()
{
if(typeof(data)!= "undefined") //if the JSON data has been received and parsed
{
alert(data.FirstName + " " + data.LastName);
}
else
{
setTimeout("ShowData()",30000); // wait some more time
}
}
in our example the JSON sent from the server will be in this form
var data = {
FirstName : 'Sanil',
Age : 24,
Role: 'Software Developer',
LastName : 'Tomar'
};
There are well defined methods that does this in jQuery. You can use the jQuery.getJSON to achieve same thing in a lot cleaner way.
Hope, this technique helps you in getting around this hurdle to access cross-site data.
♥ Happy Coding!! ♥
<digression>
Geek News: Pi (∏) to be replaced by Tau (τ) Link1 , Link2
</digression>
But so many books and manuals underplay classes in python that it mostly lives in early programmers as plain scripting language having support for procedures/methods. In reality, Python supports object-oriented programming with classes and multiple inheritance.
Here is an approximate syntactical comparison beween class declaration in C# and python:
C# Version:
public class Person
{
int Age;
public string Name;
float Height;
float Weight;
public Person(int age,float height,float weight)
{
Age = age;
Height = height;
Weight = weight;
Name = "No Name"
}
public void GetInfo()
{
system.console.WriteLine("Name: {0}",Name);
system.console.WriteLine("Weight: {0}",Weight);
system.console.WriteLine("Height: {0}",Height);
system.console.WriteLine("Age: {0}",Age);
}
}
Python Version
class Person:
Name = "No Name"
def __init__(self,age,height,weight):
self.Age = age
self.Height = height
self.Weight = weight
def GetInfo(self):
print "Name: ", self.Name
print "Weight: ", self.Weight
print "Height: ", self.Height
print "Age: ", self.Age
------------------------------------------------------------------------------------
Usage:
p = Person(20,5.11,70)
p.GetInfo()
print("\n\n")
p.Name = "Chuck Norris"
p.GetInfo()
------------------------------------------------------------------------------------
Output:
Name: No Name
Weight: 70
Height: 5.11
Age: 20
Name: Chuck Norris
Weight: 70
Height: 5.11
Age: 20
Learn more about classes and objects oriented programming in python here
]]>If you look at the CC.Net directory structure, you can find that all the project specific logs are kept at <CC.Net>\server\<project-name>\Artifacts\BuildLogs (in Default config)
So, if you have a project named MyFirstProject…
it will be in the <CC.Net>\server\MyFirstProject\Artifacts\BuildLogs

further the log files names also follow a pattern
for example, take this:
log20101125115243Lbuild.4.xml
this consists of log+<year>+<month>+<day>+<hour>+<min>+<sec>+LBuild.<build-label>.xml, so from the file name above, we can know that:
Year = 2010, month = 11, day= 25; hour = 11, min = 52, sec = 43.
If build had failed, then the file name changes to :
log+<year>+<month>+<day>+<hour>+<min>+<sec>.xml, that is the Build-Label is missing.
So I quickly wrote this powershell script, which spits out results as CSV.
Project Name, Date of Build, Build-Label, Status
_____________________________________________________________
___________________________________________________________
Hmm… Powershell is really powerful
Yesterday, while sitting at my desk doing my usual work <digression>actually computer was doing that. I was only telling him what to do </digression>.
So I was pretty much free to do other things and at that time I miss my home computer where I want to do things, like I want to see the status of my computer remotely, is it up or not and system uptime and the Intranet Apache server is running or not which is critical for some stuff.
So I came back to home, it was Friday night and wrote a python script to fetch commands from a web URL and run them in console and POST the results back to server. I set it up in task scheduler to run at specified intervals.
Unfortunately, the results were not at all up to what I wanted. The whole activity from sending commands from web page to actually execute them and display the results took quite a long time. The average round-trip time including execution was ~ 3 minutes. That’s really too slow.
There were bottlenecks in the solutions.
Solution
I realized there was a Cruisecontrol.net server that was performing some tasks like performing builds etc. I tried setting up a project on it to run the script in 5 sec intervals still the results were not up to the mark, but still there was significant reduction in round-trip = 1 minutes – 30 secs.
Later, I setup the Cruisecontrol to regularly ping the server to execute the task only if there is a command waiting to be executed at the server. This brought down the time to 10-40 seconds.
I loved it.
Following is the Project entry in the Cruisecontrol:
<project name="RCProcessor" >
<triggers>
<urlTrigger url="<URL>/command.txt" />
</triggers>
<sourcecontrol type="nullSourceControl" />
<tasks>
<exec>
<executable>cmd.exe</executable>
<buildArgs>"/c <Path-To-Script>\process.py >> commands.txt"</buildArgs>
<buildTimeoutSeconds>10</buildTimeoutSeconds>
</exec>
</tasks>
<publishers>
<xmllogger />
</publishers>
</project>
And here comes the python script…
import os
from re import split
import string
import urllib
import urllib2
import datetime
baseurl = ' < Base-URL > /'
url = baseurl + 'command.txt'
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
now = datetime.datetime.now().strftime("%m-%d-%y %H:%M")
headers = { 'User-Agent' : user_agent }
def SubmitData(url,data):
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
values = {'data' : data}
headers = { 'User-Agent' : user_agent }
encdata = urllib.urlencode(values)
req = urllib2.Request(url, encdata)
response = urllib2.urlopen(req)
the_page = response.read()
return the_page
#END SubmitData
print("Get URL: "+url)
req = urllib2.Request(url)
response = urllib2.urlopen(req)
the_page = response.read()
the_page = string.replace(the_page,"\\\\","\\")
print("Command: "+ the_page)
if (the_page != ""):
list = ""+"cmd /c " + the_page+""
for line in os.popen("cmd.exe /c" + the_page):
line = string.replace(line,"<","<")
line = string.replace(line,">",">")
list += "\r\n" + line
print(":: OUTPUT ::\n\n")
print(list)
print("\n\n")
print("SEND URL: "+baseurl + "output.php")
print(SubmitData(baseurl + "output.php","\r\n"+ list))
#END IF
That’s all folks J
Hope you like it, play around and try out new things and post it back here.
And do leave comments J
]]>This policy has been enforced to prevent session riding, for further details look this Karen Corby’s blog post on cross domain requests.
Turns out that in silverlight, HTTP requests to non-original domains are allowed if the server has exclusively allowed to accept requests. The primary way of enabling cross domain calls is through a policy file placed at the root of the server. Two types of policy files are supported:
Now, the problem is that twitter don’t have policy files placed in the server root. Possible way to get around this is to use a proxy for requests. you can make a proxy on your server, that can on application request, fetch the RSS data from twitter and send it back to your application. EASY!
but what if, you don’t want your own server proxy…
reasons:
simple! use Yahoo Pipes, why?
What is a yahoo pipe?
Content-source: http://pipes.yahoo.com/pipes/
Pipes is a powerful composition tool to aggregate, manipulate, and mashup content from around the web.
Like Unix pipes, simple commands can be combined together to create output that meets your needs:
- combine many feeds into one, then sort, filter and translate it.
- geocode your favorite feeds and browse the items on an interactive map.
- power widgets/badges on your web site.
- grab the output of any Pipes as RSS, JSON, KML, and other formats.
simply speaking, a yahoo pipe is url like this:
http://pipes.yahooapis.com/pipes/pipe.info?_id=bas782j290jq9dd2nmaklfhj93ji9d3j
you design its behaviour on a design surface
So, a yahoo pipe can be designed to take single/multiple feed URLs, fetch the feeds and provide an aggregated feed which can be consumed by your silverlight application under cross domain policy.
further, you can provide test data and see results right there.
Run it and get the aggregated RSS URL from the run screen.
The pipe, I used looks like this
http://pipes.yahooapis.com/pipes/pipe.run?_id=f0cf1b0851bd8243dbf8bd63c07b8d11&_render=rss&feedUrl=<some_feed_url>
Now fetching the data in your silverlight application is damn easy…
private string proxy = "http://pipes.yahooapis.com/pipes/pipe.run?_id=f0cf1b0851bd8243dbf8bd63c07b8d11&_render=rss&feedUrl="; private string feedUrl = "http://twitter.com/statuses/user_timeline/22100709.rss"; void DownloadFeed() { string url = proxy + feedUrl; HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(new Uri(url)); request.Method = "GET"; request.BeginGetResponse(new AsyncCallback(ResponseHandler), request); } void ResponseHandler(IAsyncResult asyncResult) { try { HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState; HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult); if (response.StatusCode == HttpStatusCode.OK) { Stream stream = response.GetResponseStream(); int len = 1024; byte[] buf = new byte[len]; int read = 0; xml = ""; do { read = stream.Read(buf, 0, len); xml += Encoding.UTF8.GetString(buf, 0, read); }while (read > 0); stream.Close(); ParseRSSFeed(xml); } } catch (System.Security.SecurityException ex) { // Do Something } }
Next, you can include Linq to Xml (add System.Xml.Linq to References) to easily and quickly parse the xml to fetch the user tweets.
You can read more about that on Scott Gu's blog post: Silverlight Tutorial Part 3: Using Networking to Retrieve Data and Populate a DataGrid
Here is, how I have done it:
The feed you get from twitter will look like this:
<?xml version="1.0" encoding="utf-16"?> <rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"> <channel> <title>Twitter / LON3WOLF</title> <link>http://twitter.com/LON3WOLF</link> <atom:link type="application/rss+xml" href="http://twitter.com/statuses/user_timeline/22100709.rss" rel="self" /> <description>Twitter updates from Sanil Singh Tomar / LON3WOLF.</description> <language>en-us</language> <ttl>40</ttl> <title>LON3WOLF: ehem... RT @Zee: awww man...RT @patrick Best toilet ever! http://twitpic.com/rcvp2 #fb</title> <item> <title>LON3WOLF: @anilbpai you mean one that looks like xkcd, if you find any tool 4 that, then please RT</title> <description>LON3WOLF: @anilbpai you mean one that looks like xkcd</description> <pubDate>Sat, 28 Nov 2009 16:40:22 +0000</pubDate> <guid>http://twitter.com/LON3WOLF/statuses/6144843401</guid> <link>http://twitter.com/LON3WOLF/statuses/6144843401</link> </item> <item> <title>LON3WOLF: @anilbpai Go to ' Block ' button-&gt; Click! Click!
</title> <description>LON3WOLF: @anilbpai Go to ' Block ' button-&gt; Click! Click!
</description> <pubDate>Fri, 27 Nov 2009 18:38:03 +0000</pubDate> <guid>http://twitter.com/LON3WOLF/statuses/6119125496</guid> <link>http://twitter.com/LON3WOLF/statuses/6119125496</link> </item> </channel> </rss>
You can use Linq to XML in following way:
public class item { public string title; public string description; public string pubDate; public string guid; public string link; } public void ParseRSSFeed(string xmlContent) { XDocument rss = XDocument.Parse(xmlContent); var tweets = from feed in rss.Descendants("channel").Descendants("item") select new item { guid = (string) feed.Element("guid"), pubDate = (string)feed.Element("pubDate"), title = (string)feed.Element("title"), description = (string)feed.Element("description"), link = (string)feed.Element("link") }; Status = new item[tweets.Count()]; //Copy description to status int count = 0; foreach (var tweet in tweets) { Status[count] = tweet; count++; } }
Links:
Source Code: Download
Application: Download
This policy has been enforced to prevent session riding, for further details look this Karen Corby’s blog post on cross domain requests.
Turns out that in silverlight, HTTP requests to non-original domains are allowed if the server has exclusively allowed to accept requests. The primary way of enabling cross domain calls is through a policy file placed at the root of the server. Two types of policy files are supported:
Now, the problem is that twitter don’t have policy files placed in the server root. Possible way to get around this is to use a proxy for requests. you can make a proxy on your server, that can on application request, fetch the RSS data from twitter and send it back to your application. EASY!
but what if, you don’t want your own server proxy…
reasons:
simple! use Yahoo Pipes, why?
What is a yahoo pipe?
Content-source: http://pipes.yahoo.com/pipes/
Pipes is a powerful composition tool to aggregate, manipulate, and mashup content from around the web.
Like Unix pipes, simple commands can be combined together to create output that meets your needs:
- combine many feeds into one, then sort, filter and translate it.
- geocode your favorite feeds and browse the items on an interactive map.
- power widgets/badges on your web site.
- grab the output of any Pipes as RSS, JSON, KML, and other formats.
simply speaking, a yahoo pipe is url like this:
http://pipes.yahooapis.com/pipes/pipe.info?_id=bas782j290jq9dd2nmaklfhj93ji9d3j
you design its behaviour on a design surface
So, a yahoo pipe can be designed to take single/multiple feed URLs, fetch the feeds and provide an aggregated feed which can be consumed by your silverlight application under cross domain policy.
further, you can provide test data and see results right there.
Run it and get the aggregated RSS URL from the run screen.
The pipe, I used looks like this
http://pipes.yahooapis.com/pipes/pipe.run?_id=f0cf1b0851bd8243dbf8bd63c07b8d11&_render=rss&feedUrl=<some_feed_url>
Now fetching the data in your silverlight application is damn easy…
private string proxy = "http://pipes.yahooapis.com/pipes/pipe.run?_id=f0cf1b0851bd8243dbf8bd63c07b8d11&_render=rss&feedUrl="; private string feedUrl = "http://twitter.com/statuses/user_timeline/22100709.rss"; void DownloadFeed() { string url = proxy + feedUrl; HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(new Uri(url)); request.Method = "GET"; request.BeginGetResponse(new AsyncCallback(ResponseHandler), request); } void ResponseHandler(IAsyncResult asyncResult) { try { HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState; HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult); if (response.StatusCode == HttpStatusCode.OK) { Stream stream = response.GetResponseStream(); int len = 1024; byte[] buf = new byte[len]; int read = 0; xml = ""; do { read = stream.Read(buf, 0, len); xml += Encoding.UTF8.GetString(buf, 0, read); }while (read > 0); stream.Close(); ParseRSSFeed(xml); } } catch (System.Security.SecurityException ex) { // Do Something } }
Next, you can include Linq to Xml (add System.Xml.Linq to References) to easily and quickly parse the xml to fetch the user tweets.
You can read more about that on Scott Gu's blog post: Silverlight Tutorial Part 3: Using Networking to Retrieve Data and Populate a DataGrid
Here is, how I have done it:
The feed you get from twitter will look like this:
<?xml version="1.0" encoding="utf-16"?> <rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"> <channel> <title>Twitter / LON3WOLF</title> <link>http://twitter.com/LON3WOLF</link> <atom:link type="application/rss+xml" href="http://twitter.com/statuses/user_timeline/22100709.rss" rel="self" /> <description>Twitter updates from Sanil Singh Tomar / LON3WOLF.</description> <language>en-us</language> <ttl>40</ttl> <title>LON3WOLF: ehem... RT @Zee: awww man...RT @patrick Best toilet ever! http://twitpic.com/rcvp2 #fb</title> <item> <title>LON3WOLF: @anilbpai you mean one that looks like xkcd, if you find any tool 4 that, then please RT</title> <description>LON3WOLF: @anilbpai you mean one that looks like xkcd</description> <pubDate>Sat, 28 Nov 2009 16:40:22 +0000</pubDate> <guid>http://twitter.com/LON3WOLF/statuses/6144843401</guid> <link>http://twitter.com/LON3WOLF/statuses/6144843401</link> </item> <item> <title>LON3WOLF: @anilbpai Go to ' Block ' button-&gt; Click! Click!
</title> <description>LON3WOLF: @anilbpai Go to ' Block ' button-&gt; Click! Click!
</description> <pubDate>Fri, 27 Nov 2009 18:38:03 +0000</pubDate> <guid>http://twitter.com/LON3WOLF/statuses/6119125496</guid> <link>http://twitter.com/LON3WOLF/statuses/6119125496</link> </item> </channel> </rss>
You can use Linq to XML in following way:
public class item { public string title; public string description; public string pubDate; public string guid; public string link; } public void ParseRSSFeed(string xmlContent) { XDocument rss = XDocument.Parse(xmlContent); var tweets = from feed in rss.Descendants("channel").Descendants("item") select new item { guid = (string) feed.Element("guid"), pubDate = (string)feed.Element("pubDate"), title = (string)feed.Element("title"), description = (string)feed.Element("description"), link = (string)feed.Element("link") }; Status = new item[tweets.Count()]; //Copy description to status int count = 0; foreach (var tweet in tweets) { Status[count] = tweet; count++; } }
Links:
Source Code: Download
Application: Download
We all (The Programmers) write handy tools and other hell things that can make our life easier (or harder). We don’t mind it sharing it with others. They are tiny apps/utilities created just for fun or some serious job, made in free time when some idea strikes you.
With the idea of sharing those utilities and source code, here I am presenting Code Garage. Here you can download the applications or use the Source Code, in a way you want.
License??
Oh! yes it does comes with a license, its WTFPL.
What is that??
WTFPL : Do What The Fuck You Want Public License. (here is original link )
Seriously, What’s that?
Well, here is how it binds you:
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar
14 rue de Plaisance, 75014 Paris, France
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
In Summary: You can do whatever you want, you are FREE!
Q: Can I do that?
A: yes, you can
Q: And that?
A: duh! Yes
Q: Can I add my code here?
A: Yes you can, though I would like to see an entire your own blog dedicated to that. but, still if you want you are welcome, just send me an email
Last Word: I hold no liabilities, if you happen to use any code/utilities from here and something bad happens to you, including any loss incurred in any form. That means I am free too from any liabilities, you can’t sue me in anyway.
Said that, here is a list of the utilities/source code etc that I have uploaded and published plus those that I plan to upload:
Yeah! it covers lamest things, I happen to write.
Still have questions?
]]>Side Note: I am big fan of that blog, its awesome and enlightening
Well, here is an excerpt of that post:
Check out the code below:
using System.Linq;
class Program
{
static void Main()
{
int[] data = { 1, 2, 3, 1, 2, 1 };
foreach (var m in from m in data orderby m select m)
System.Console.Write(m);
}
}Now, the question is:
Is this code valid or not??
If valid, how?
If not valid, why?
(Source: Eric Lippert’s Blog)
So, I worked on that problem posted some comments there, and presenting it again here in the form of a post.
The moment I read the problem, things started running in my mind around
var m in from m in data orderby m select m
as you can perceive, m is being used in two different contexts, first as a enumerator in LINQ query: " from m in data orderby m select m "
and the "var m " part in foreach. The question here: Can that possibly work?
Luckily, I was honing my skills in Reflection (System.Reflection) at that time, I get across a phrase in this book about foreach block (it says Cs compiler adds some temp. variable to smooth out operations like
a += 2;
or
foreach(var m in M){}
along with that there was also a prenotion that something "magical" happens when you encounter such situation, and whole code behaves like it is working in scopes (The blocks of { }).
So, the possible explanation, that came to my mind about this problem was :
the thing "var m in from m in data orderby m select m"
breaks up into two scopes : { var m } in { from m in data orderby m select m }
or in other terms var m in {from m in data orderby m select m}
We can proceed to further abstractions
var m = {from m’ in data order by m’ select m’}
that would eventually looks like
var m in m’ // where m’ is enumerable
[
Oops, m' is not a valid name for a variable, but good for human beings]
OK! I have a possible explanation, now how to confirm that its right and not a conjecture.
I fired RSS Bandit and rushed to Eric Lippert’s blog…
<digression>
x-(
Though I like reading blogs, but Internet, blogs and twitter (a.k.a Knowledge Supernova) provide so much information to absorb, I occasionally procrastinate reading RSS and let them aggregate scheduled to be read on weekends, after I am exhausted from celebrating TGIF and TGIS, so I missed the Eric Lipperts blog post that mentioned this problem
![]()
</digression>
I fired RSS Bandit and rushed to Eric Lippert’s blog and tried to find out where this problem is being discussed, and I failed to figure its occurrence since it was phrased at the end of blog post and I was flipping over top.
This made me more curious to find the real answer, so I fired VS, hit Ctrl + C, Ctrl+ V and some tabs, ran it and yes it was running fine, just like you would expect.
But, that doesn’t answer actually what concerns me: Is my explanation is completely right?
Suddenly, an idea struck me: Utilize Reflection
Advantage was that, it will cause extra practice much needed to get comfortable with reflection
So, I started writing code:
First, I wrote
using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Collections.Generic; class Program { static void Main() { int[] data = { 1, 2, 3, 1, 2, 1 }; foreach (var m in from m in data orderby m select m) System.Console.Write(m); new Analyse().Run(); System.Console.ReadKey(); } } class Analyse { public void Run() { Assembly asm = Assembly.GetAssembly(typeof(Program)); MethodBody mb = asm.EntryPoint.GetMethodBody(); System.Console.WriteLine("\nMethod Name: "+asm.EntryPoint.Name); foreach (var locals in mb.LocalVariables) { System.Console.WriteLine("\n {0}", locals.LocalType.FullName); } System.Console.ReadKey(); } }
The Run method would actually list all the variables that are present after actual compilation, this will include the variables we have declared explicitly or implicitly as well as other variables introduced by compiler to store temporary results and perform calculations.
If you run it you will get output:
111223
Method Name: Main
System.Int32[]
System.Int32
System.Collections.Generic.IEnumerator`1[[System.Int32, mscorlib, Version=2.0.0.
0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]System.Boolean
Ok! Let me set a context, before I go for explaining things here
change the body of main() method inside program class to
using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Collections.Generic; class Program { static void Main() { int[] data = { 1, 2, 3, 1, 2, 1 }; foreach (var num in data) { System.Console.Write(num); } new Analyse().Run(); System.Console.ReadKey(); } } ... contd.
How the output changes:
123121
Method Name: Main
System.Int32[]
System.Int32
System.Int32[]
System.Int32
System.Boolean
A little explanation
the first system.Int32[] is this array int[ ] data = { 1, 2, 3, 1, 2, 1 };
next System.Int32 will receive value at each iteration and will be used in Write() [this is our var m]
the second System.Int32[] refers to ForEach’s copy of array. Remember foreach doesn’t allow changing contents, so it makes a copy.
the second Int32 is an index to track current iterator location
last is a boolean which stores the result of condition check
Note: this is again guess work, but still quiet predictable ![]()
Note that there are two occurrence of System.Int32, than how can I figure out, what is the purpose of the second one and last one
so, we again change the main() body to
static void Main() { char[] ch = { 'a', 'b', 'c' }; foreach (var num in ch) { System.Console.Write(num); } new Analyse().Run(); System.Console.ReadKey(); } ... ..
the output changes to :
abc
Method Name: Main
System.Char[]
System.Char
System.Char[]
System.Int32
System.Boolean
so, you can see that, system.char (replacing first System.Int32) is getting the assigned value that will be Write() outputted, and thus by comparing the ordinal similarity between the two outputs, it would be right to think that first System.Int32 is receiving the current value of data (index to which, iteration is pointing).
Back to our actual code, analysing the output
111223
Method Name: Main
System.Int32[]
System.Int32
System.Collections.Generic.IEnumerator`1[[System.Int32, mscorlib, Version=2.0.0.
0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]System.Boolean
line by line, we can see that
System.Int32[ ]
(the actual data[] array)
System.Int32
(that will receive value at each iteration and will be WriteLined/outputted)
System.Collections.Generic.IEnumerator`1[[System.Int32, mscorlib blah blah blah... ]]
( the generic IEnumerator generated from LINQ expression obtained, now all classes implementing IEnumerator has a method called MoveNext( ), hence it will not require any additional Sytem.int32 indexer, hence here it is absent in output)
System.Boolean
(condition check result as previously stated)
From all this, we get that compiler handle duplicate references smartly, until we play by his rules and work according to C# language specs
This technique forms (No, I didn’t discovered it) another tool to analyse the code behaviour.
As a side note, other such techniques you are familiar with are:
finally, on the other day when I was reading posts aggregated in RSS Bandit from coding horror, many other blogs and somewhere in middle Eric’s blog, I find this problem hiding at the bottom of the blog post, and by reading the blog post you can get the explanation and It seems that, I stand correct
Still if you think, I am wrong somewhere, please comment here. I will be happy to get the right facts.
Edit: I just found out that, Eric also posted next post in continuation to that problem, where he explains excellently the behaviour of this code, in his own way.
]]>