Monday, July 21, 2008

JavaScript and Java are Pass By Value

Proof that JavaScript and Java are Pass By Value



Pass by value and pass by reference can be daunting at times, and I too have been confused and frustrated at all of the babbling about whether or not Java is one or the other, that is, until I saw an article featuring the Litmus test. I've seen the Litmus test in college, but it didn't make sense completely until reading Scott Stanchfield's "Dammit" article.

Today I was reading Jeff Cogswell's article asserting that JavaScript is pass by value. The blog author is indeed correct in his assertions; however, there were many comments rebutting his arguments. I thought it would be best to support his arguments by applying the Litmus test to JavaScript to prove once and for all whether or not JavaScript is pass by value or pass by reference.

Java is clearly pass by value. Scott Stanchfield's statement says it best: "Objects are not passed by reference. A correct statement would be Object references are passed by value."


The JavaScript Litmus Test



I decided to apply the Litmus test to JavaScript and see what the results are. Here is what I have so far:


function doLitmusTest() {
     var a1 = 5;
     var a2 = 7;
     swap(a1,a2);
     alert(a1 + ","+a2);
}

function swap(a,b) {
    var temp = a;
    a = b;
    b = temp;
}

window.addEventListener("load",function() { doLitmusTest(); },true);



The output is as follows:

5,7

The values were not swapped. JavaScript fails the Litmus test, as Java did. This means that JavaScript is also pass by value.

In Java, there is a workaround to being able to implement the swap function, and it also works in JavaScript:


function anotherTest() {
     var obj1 = { value: 5 }; // JSON notation
     var obj2 = { value: 7 }; // JSON notation
     swapValue(obj1,obj2);
     alert(obj1.value + "," + obj2.value);
}

function swapValue(objA,objB) {
     var temp = objA.value;
     objA.value = objB.value;
     objB.value = temp;
}

window.addEventListener("load",function() { anotherTest(); },true);



The output is:
7,5

In Java, data can be "wrapped" in an object to allow the value to be changed. JavaScript behaves in the same manner. All values, both primitives and object references are passed by value. With primitives, changes we make to one copy of a variable do not affect changes to another copy.

The rule is the same with Object references. Objects are not passed in as parameters in Java or JavaScript, object references are passed as parameters. References point to a specific location in memory. Three references can all point to the same location, so if the data located at that spot in memory is changed, the change will be reflected for all of the references that point to that spot.

However, changes to the reference itself are not reflected. A rule of thumb to remember is that when implementing the swap method, you can only change data by calling setter and getter methods, or by accessing public properties. However, making changes to the object reference instruct the object reference to point to a different location. This is why swapValue worked as expected while swap did not.

Below is a sequence of "visual art" to demonstrate the concepts visually:


new operator uses new memory space

Object A and Object B are instantiated and new memory is allocated on the heap.



using new on object A creates new space in memory

Object A is assigned a reference to new memory space because the "new" keyword was used.



using setter changes value in memory location

The value of the object referenced by B is changed to a new value, but the object reference still points to the same location in memory.

For A, the "new" operator created new space in memory and instantiates a new object. The "12" is located in a different spot in memory.

B, on the other hand, has a value that was set using a setter method. Thus, the value has changed from "7" to "2" without destroying the original object.



multiple objects reference the same memory space
Objects A, C, and D all point to the same place in memory. If a setter method is called on one of the object references, the value is changed in all 3 object references because they all point to the same location in memory.

A good analogy to use to explain this concept is "nicknames". For instance, my name is James, but people also refer to me by Jim. Additionally, I've been called "Mort" before as well. All three names point to the same object, me! In the example I've shown you, A, C, and D are all names of the same object.

Sunday, July 13, 2008

XSLT Transformations with XML Namespaces

As of the date of this article, there are currently not a lot of resources on the Internet regarding how to transform XML that contains namespaces. Yahoo's Weather Web Services API returns data in the form of RSS, and this data is formatted not only with elements and attributes, but also with namespaces.

I'm experimenting with the Yahoo Weather API for a potential project I may work on. Considering that there may be other Weather API's used, it makes more sense from an architectural design standpoint to tranform Yahoo's data into my own XML data structure. This ensures that if the client decides that he/she likes Google's Weather API, or the Fox News API, all we need to do is create a new XSLT stylesheet to convert the data into the format recognized by our server.

Here is part of the Yahoo Weather Data, taken from here.:


<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<rss version="2.0" xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">
<channel>

<title>Yahoo! Weather - Portland, OR</title>
<link>http://us.rd.yahoo.com/dailynews/rss/weather/Portland__OR/*http://weather.yahoo.com/forecast/97206_f.html</link>
<description>Yahoo! Weather for Portland, OR</description>
<language>en-us</language>
<lastBuildDate>Sat, 28 Jun 2008 4:53 pm PDT</lastBuildDate>
<ttl>60</ttl>
<yweather:location city="Portland" region="OR" country="US"/>

<yweather:units temperature="F" distance="mi" pressure="in" speed="mph"/>
<yweather:wind chill="101" direction="300" speed="10" />
<yweather:atmosphere humidity="22" visibility="10" pressure="29.82" rising="2" />
<yweather:astronomy sunrise="5:24 am" sunset="9:03 pm"/>
<image>
<title>Yahoo! Weather</title>
<width>142</width>
<height>18</height>
<link>http://weather.yahoo.com</link>
<url>http://l.yimg.com/us.yimg.com/i/us/nws/th/main_142b.gif</url>
</image>
<item>

<title>Conditions for Portland, OR at 4:53 pm PDT</title>
<geo:lat>45.52</geo:lat>
<geo:long>-122.68</geo:long>
<link>http://us.rd.yahoo.com/dailynews/rss/weather/Portland__OR/*http://weather.yahoo.com/forecast/97206_f.html</link>
<pubDate>Sat, 28 Jun 2008 4:53 pm PDT</pubDate>
<yweather:condition text="Fair" code="34" temp="101" date="Sat, 28 Jun 2008 4:53 pm PDT" />
<description><![CDATA[
<img src="http://l.yimg.com/us.yimg.com/i/us/we/52/34.gif"/><br />
<b>Current Conditions:</b><br />
Fair, 101 F<BR />
<BR /><b>Forecast:</b><BR />
Sat - Mostly Clear. High: 97 Low: 65<br />
Sun - Mostly Sunny. High: 91 Low: 66<br />
<br />
<a href="http://us.rd.yahoo.com/dailynews/rss/weather/Portland__OR/*http://weather.yahoo.com/forecast/USOR0275_f.html">Full Forecast at Yahoo! Weather</a><BR/>
(provided by The Weather Channel)<br/>
]]></description>
<yweather:forecast day="Sat" date="28 Jun 2008" low="65" high="97" text="Mostly Clear" code="33" />
<yweather:forecast day="Sun" date="29 Jun 2008" low="66" high="91" text="Mostly Sunny" code="34" />
<guid isPermaLink="false">97206_2008_06_28_16_53_PDT</guid>
</item>

</channel>
</rss><!-- api1.weather.sp1.yahoo.com compressed/chunked Sat Jun 28 17:19:32 PDT 2008 -->



Note that the temperature and other weather data is stored within elements that are part of the yweather namespace. The XSLT stylesheet below demonstrates how to obtain the temp attribute from the yweather:condition element:


<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0">

<xsl:template match="/">
<html>
<body>
<h2>Weather</h2>
<table border="1">
<xsl:for-each select="rss/channel">
<tr>
<td>title</td>
<td class="title"><xsl:value-of select="title" /></td>
</tr>
<tr>
<td>link</td>
<td class="link"><xsl:value-of select="link" /></td>
</tr>
<tr>
<td>curCond</td>
<td class="curCond">
<xsl:value-of select="//yweather:condition/@text" />
</td>
</tr>
<tr>
<td>curTemp</td>
<td class="curTemp">
<xsl:value-of select="//yweather:condition/@temp" />
</td>
<td id="curTemp">
<xsl:value-of select="//yweather:condition/@temp" />
</td>
</tr>
<xsl:for-each select="//yweather:forecast">
<tr>
<td>forecast</td><td class="day">day: <xsl:value-of select="@day" /></td>
</tr>
<tr>
<td></td><td class="date">date: <xsl:value-of select="@date" /></td>
</tr>
<tr>
<td></td><td class="low">low: <xsl:value-of select="@low" /></td>
</tr>
<tr>
<td></td><td class="high">high: <xsl:value-of select="@high" /></td>




On another note, I've done XML conversions before the hard way: By parsing the XML with PHP or JSP and dynamically rebuilding the XML! While this would also work to solve my problem, using XSLT will allow me to keep the transformation layer separate from the business logic.

Although this was somewhat time consuming getting started with XSLT and converting XML with namespaces, I can already feel the weight being lifted off my mind knowing that changing my data sources won't involve troubleshooting PHP errors!

Saturday, July 5, 2008

Share VMWare Image between Dual-Boot Operating Systems


How to Share a VMWare Image Between Windows XP and Ubuntu 8.04


Sharing a VMWare Image in a dual-boot setup involves the following prerequisites:

- One ntfs partition with Windows XP Professional installed
- One ext3 partition with Ubuntu 8.04 installed
- One fat32 partition, shared between Ubuntu and Windows
- At least 1GB of RAM
- VMPlayer installed in both Windows XP and Ubuntu 8.04
- VMImages, stored on the fat32 partition


Stored on the fat32 partition is one Windows XP Home VMImage. I don't have VMWare Workstation. So you may be wondering how I was able to create my own Windows XP Home image. I'll get to that later.

I first boot into the Windows XP Home installation using the Windows XP Pro host. I moved some files around, made some changes to some files. Then shutdown the VMImage. I reboot the computer into Ubuntu 8.04, started VMPlayer, and boot into the very same Windows XP Home image I was just working with on the XP host. My changes were all there!

Windows XP VMPlayer on Ubuntu select copied

When I first started up the VMImage in Ubuntu, the system asked me if I moved or copied the VMImage. Well, I didn't move it, but I didn't copy it either. Since I wasn't sure what option to pick, I selected the "copied" option recommended by VMPlayer if you don't know whether or not you moved or copied the image. This will happen again when I switch back to the Windows host. So far, selecting "copied" has not negatively affected performance.

The first time booting the image in the new host, networking didn't immediately work. Wait a few minutes and it may fix itself. You can also go into VMWare tools, if it's installed, and make sure your Ethernet card is enabled. So far, I've had no issues with networking.

I'm very impressed with VMPlayer! I can run Windows XP in a VMimage in both Windows and Linux. It's stable, fast, and allows me to work on Windows projects on both Ubuntu and Windows hosts.

Boot Windows XP in Ubuntu using VMPlayer


Using Microsoft Virtual PC to Create Image and Convert with VMWare Converter



Previously, I was using Microsoft Virtual PC 2007, which wasn't cross-compatible with Linux. To answer the above unanswered question of how I created a Windows XP Home VMWare image without VMWare Workstation, I used VMWare Comverter to convert my Windows XP Home Virtual PC image to VMWare. In Virtual PC, it took a long time to boot up. Once booted, response was slow and unusable. I quit using the Virtual PC image long ago because it was simply too slow.

In VMPlayer, I feel that the Guest operating system runs smoother than the Windows XP host itself! I'd recommend this setup for anyone who wants to run Windows from Linux and Windows from Windows. Additionally, although Virtual PC is slow, it's a great tool to allow you to create a Virtual image and then convert it to VMWare using the VMWare Converter.

UPDATE: I've been using this setup for over a month and I'm still happy with it!
Google