Tolstoy for bedtime
Last night I read Tolstoy to my four-year-old.
No, it wasn’t Leo Tolstoy’s War and Peace; it was Alexei Tolstoy’s The Enormous Turnip.
Worthy of a Moleskine
When I first heard about Moleskines I immediately fell in love with them. Just the idea of carrying around these notebooks – the type used by van Gogh, Picasso and Hemingway, no less! – felt awe-inspiring.
They are available in Kuala Lumpur, and the prices are perhaps more awe-inspiring than the notebooks themselves. The smallest and thinnest costs RM25 for two (promotion price). Looking at what I scribble in my throwaway, sub-ringgit notebooks – random to-do items, shopping lists, phone numbers – it’s very obvious that Moleskines are not for me. They’re for poets, writers, and painters, not for ordinary people with everyday lives.
My wife, however, can paint. So yesterday we drove down to Czip Lee Bangsar and she got herself some art supplies plus a Moleskine Folio Watercolour Album A4. She has already filled two pages with her watercolours. Let me say this: she is worthy of a Moleskine.
I almost bought the RM25 set-of-two but put it back at the last minute. But I did get myself an RM9 Faber-Castell PITT artist pen. I’m using it to scribble random to-do items, shopping lists, phone numbers, etc. It’s so nice.
By value, by reference: by analogy
Here’s my best attempt to explain C# value types and reference types, and “pass by value” and “pass by reference” to a newbie. (Not you, of course.)
Value types
A piece of paper, on which is written the number 5. You use this number to calculate something.
Reference types
A piece of paper, on which is written a memory location. You then go to the memory location in order to access an object.
(Aside: the “object reference not set to an instance of an object” exception means that the piece of paper has the special value of “unspecified”, and when you try to use this piece of paper to access an object, you aren’t able to.)
(Another aside: in C#, by default, you aren’t able to do anything with references except to use it to access an object. In C and C++, however, you could perform arithmetic on references – powerful and dangerous.)
Pass by value
I’m a function. You hand me a piece of paper. I take out my own piece of paper, copy down what’s written on your piece of paper, and give your piece of paper back to you. Whatever I scribble on my piece of paper doesn’t affect your piece of paper.
Pass by reference
I’m a function. You hand me a piece of paper. I write on your piece of paper and give it back to you. Your piece of paper is definitely affected.
Passing reference types by value
I’m a function. You hand me a piece of paper with a memory location written on it. I take out my own piece of paper, copy down the memory location, and give your piece of paper back to you. I can’t change what’s on your piece of paper, but I can affect your object.
Passing reference types by reference
I’m a function. You hand me a piece of paper with a memory location written on it. I rub out the memory location, write a new memory location, and give back the piece of paper to you. You are now referencing another object in the new memory location.
Strings
Strings are a special case. Technically they’re reference types, but for the sake of convenience, we’re able to treat strings as value types. Although we’re passing the memory locations of our strings to functions, we don’t have to worry about these functions modifying our strings. This is because strings are immutable, like so:
class ImmutableType
{
private int _value;
public ImmutableType(int value)
{
_value = value;
}
public int Value
{
get
{
return _value;
}
}
}
class Program
{
public static void Main()
{
ImmutableType x = new ImmutableType(5);
// will output 5
Console.WriteLine(x.Value);
// set y to refer to the same object as x
ImmutableType y = x;
// will output 5
Console.WriteLine(y.Value);
// illegal, no set accessor, so our object is safe
//y.Value = 6;
// no choice but to create a new object
y = new ImmutableType(6);
}
}
When all you have is a hammer
… everything looks like a nail. The point I would like to make here is this: when all you know is C#, everything looks like a class.
(Note: When I say C#, I mean Java or C#. At the core both are the same. I only mean to avoid from having to repeatedly say “Java/C#” which is distracting.)
After having had to continually switch between PHP and C# over the course of a year, I’ve come to realize that different languages are better at solving different types of problems. Actually it’s not really about the language per se (which is just syntax), but the paradigm. PHP is excellent for UI-driven websites with fluid requirements and short release cycles. C# is excellent for Windows apps and web services. Java is excellent for mid-tier components that can run on Unix. C++ is excellent for writing device APIs. VBA on MS Access is excellent for form-driven apps that come with their own database on file. Perl is excellent for text processing.
Thus, the more languages you know, the higher the likelihood of your being able to use the best tool for the job. Ultimately, that’s all a programming language is: a tool, suited for a particular purpose.
For some reason there are people who identify themselves with a particular language. They have a mental block when it comes to learning new programming languages. I think that’s a mistake. Wouldn’t it be better to be able to use the best programming language for the job at hand, and to identify oneself with this ability?
Having said that, it isn’t easy to get the chance to practise a new language for a real project. But at the very least one should keep an open mind, and to jump in without hesitation when the opportunity arises.
P.S. There are also other variations to the first paragraph: when all you know is PHP, everything looks like an ordered map; when all you know is Lisp, everything looks like a linked list; when all you know is JavaScript, everything looks like a collection of named values.
Calling a SOAP web service from PHP
The SOAP binding is RPC/encoded, and the WSDL is not published.
Using the PHP SoapClient:
define('NEWLINE', "<br />\n");
// SOAP client
$options = array
(
'location' => 'https://example.com:1234/sample/service',
'uri' => 'http://example.com/sample/namespace/data',
'style' => SOAP_RPC,
'use' => SOAP_ENCODED,
'trace' => true // in conjunction with $soapClient->__getLastRequest() below
);
$soapClient = new SoapClient(null, $options);
// SOAP header
$nsHeader = 'http://example.com/sample/namespace/security';
$elementName = 'Security';
$usernameToken->Username = new SoapVar('user9', XSD_STRING, null, null, null, $nsHeader);
$usernameToken->Password = new SoapVar('pass1234', XSD_STRING, null, null, null, $nsHeader);
$content->UsernameToken = new SoapVar($usernameToken, SOAP_ENC_OBJECT, null, null, null, $nsHeader);
$soapHeader = new SoapHeader($nsHeader, $elementName, $content);
$soapHeaders[] = $soapHeader;
$soapClient->__setSoapHeaders($soapHeaders);
// SOAP call
$method = 'getData';
$parameters = array
(
new SoapParam('abcdef', 'param1'),
new SoapParam(12345, 'param2')
);
$success = true;
try
{
$result = $soapClient->__soapCall($method, $parameters);
}
catch (SoapFault $fault)
{
echo "Fault code: {$fault->faultcode}" . NEWLINE;
echo "Fault string: {$fault->faultstring}" . NEWLINE;
$success = false;
}
echo $soapClient->__getLastRequest(); // output the request XML
if ($success)
{
echo "<pre>\n";
print_r($result);
echo "</pre>\n";
}
if ($soapClient != null)
{
$soapClient = null;
}
Using curl:
define('NEWLINE', "<br />\n");
$ch = curl_init();
$data = '<soapenv:Envelope xmlns:ns2="http://example.com/sample/namespace/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://example.com/sample/namespace/data">
<soapenv:Header>
<ns2:Security>
<ns2:UsernameToken>
<ns2:Username>user9</ns2:Username>
<ns2:Password>pass1234</ns2:Password>
</ns2:UsernameToken>
</ns2:Security>
</soapenv:Header>
<soapenv:Body>
<ns1:getData soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<param1 xsi:type="xsd:string">abcdef</param1>
<param2 xsi:type="xsd:integer">12345</param2>
</ns1:getData>
</soapenv:Body>
</soapenv:Envelope>';
$fh = fopen('soap_response.txt', 'w');
curl_setopt($ch, CURLOPT_URL, 'https://example.com:1234/sample/service');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
//curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSLKEY, 'sample.pem');
curl_setopt($ch, CURLOPT_FILE, $fh);
if (curl_exec($ch) === false)
{
echo "Curl error: " . curl_error($ch) . NEWLINE;
}
else
{
echo "Operation completed successfully" . NEWLINE;
}
curl_close($ch);
fclose($fh);
