Friday, March 5, 2010

Git's environment filter

This is a thing I keep on forgetting although I've done it several times. So, I'm writing a blog post hoping it will help me memorize this.

So... how do you rewrite Git's history, specifically the environment variables? With git filter-branch of course. I frequently need it in order to change the author and committer email addresses (either from personal to work or the other way around).



git filter-branch --env-filter 'export GIT_AUTHOR_EMAIL="email@address.com"' HEAD
git filter-branch --env-filter 'export GIT_COMMITTER_EMAIL="email@address.com"' HEAD



Don't forget that there are two email addresses, OK? The author's and committer's one. Oh, and no spaces around the equal sign.

For a more complicated situation see this answer on serverfault.com.

Friday, June 5, 2009

CSS for Firefox only

So, how do you write CSS code that will be understood only by Firefox?

Same question was asked by someone on stackoverflow.com. My first attempt was to use XBL and Mozilla's proprietary -moz-binding CSS extension in order to run some JavaScript that will eventually load the intended CSS rules. This solution was inspired by Dean Edwards' moz-behaviors library and it looks like this:

index.html

<!DOCTYPE html>

<
html>
<
head>
<style type="text/css">
body {
-moz-binding: url(ff.xml#load-mozilla-css);
}
</style>
</head>
<
body>

<
h1>This should be red in FF</h1>

<
/body>
<
/html>


ff.xml

<?xml version="1.0"?>

<bindings xmlns="http://www.mozilla.org/xbl">
<binding id="load-mozilla-css">
<implementation>
<constructor>
<![CDATA[
var link = document.createElement("link");
link.setAttribute("rel", "stylesheet");
link.setAttribute("type", "text/css");
link.setAttribute("href", "ff.css");

document.getElementsByTagName("head")[0]
.appendChild(link);
]]>
</constructor>
</implementation>
</binding>
</bindings>


ff.css

h1 {
color: red;
}



But I felt that there should be a better solution. So I kept digging on MDC. After a couple of clicks I discovered the easiest solution out there for targeting just the Firefox browser in our CSS. It uses a Mozilla specific at-rule, called @-moz-document, and it's actually intended for user styling.

Here's the final solution

<!DOCTYPE html>

<
html>
<
head>
<style type="text/css">
@-moz-document url-prefix() {
h1 {
color: red;
}
}
</style>
</head>
<
body>

<
h1>This should be red in FF</h1>

<
/body>
<
/html>


A word of caution

We all know how many hours Internet Explorer conditional comments have saved us, but I believe Firefox is a much, much better browser, so please think twice before using the above trick. I'm pretty sure there must be some other way. We don't want to maintain three different stylesheets, for IE, FF and the rest of the browsers out there.

Tuesday, April 28, 2009

JScript deviations from ECMAScript 3

Just found a great resource of "things" that are specific to JScript and are not conforming to the ECMAScript 3 standard. Found it on a MSDN blog post from 2007. Enjoy, 87 pages of standards deviations (aka bugs)! Here's the PDF.

Friday, April 3, 2009

Lambdas and closures in PHP 5.3

Beginning with PHP 5.3 we'll be able to write anonymous functions and build closures around them - almost the same way we do it in JavaScript. I'd like to introduce these to those of you unaware of these new possibilities in this little blog post.

Defining a lambda


The most simple way to define a lambda can be find below. It's exactly the same way JavaScript handles it. One has to assing a function to a variable.
<?php

$lambda = function() {
return 'Hello World';
};
// <- this semicolon is mandatory, unlike JavaScript

echo $lambda();

Creating closures


However, if we want closures, we have to do something more and this because the way scope is designed in PHP where functions don't get easy access to variables declared outside them. If we want that with a normal (old style) function, we need to import them using the global keyword. Following the same idea, in order to capture a variable into a closure we need to use it:
<?php

$word = ' World';
$lambda = function() use($word) {
return 'Hello' . $word;
};

echo $lambda();

Mutable closures


Now, our anonymous functions has access to $word. But there's a gotcha right here. It has read only access to $word. We may try to modify $word inside our function, but those changes won't be visible outside it. So, here we are, introducing the third thing we need to know about lambdas and closures in PHP. In order to be able to modify a closed variable, we need to import it using the reference operator:
<?php

$word = ' World';
$lambda = function() use(& $word) {
$result = 'Hello' . $word;
$word = 'Bye World';
return $result;
};

echo $lambda();
echo $word;

This time, $word can and will be modified. The variable inside the closure is mutable.

Some history about the future


Although, as of yet, a stable version of PHP 5.3 is not yet out, I should mention that in the process of bringing lambdas and closures to the language there was a particular property of these in that they were able to automagically import the $this pointer if the function was defined inside a class. Not long after, some people thought about writing PHP in the prototypal style of JavaScript, thus there were some discussion that lead the PHP internals to temporarily remove the magic import feature. The main reason was that they had to push the final version out sooner and any new feature would have meant delays. Nevertheless, this feature has been postponed for PHP 6 in which we may get some niceties that should allow us to more easily write code in a monkey patching/prototypal style.

Wednesday, April 1, 2009

What's new in PHP 5.3

A few weeks ago, PHP 5.3 RC1 has been released and I expect the final version to be out in no more than a month. I'm watching its development since the beginning of 2008 and am really eager to see it in production. The reason for this impatience is that it brings really cool features to the language and I'd like to enumerate some of them in order of my preferences. Initially I also wanted to briefly describe them, but apparently there was to much to talk about in just one post, therefore each feature in the list below will, eventually, point to a more detailed post about the respective feature. So here's what I like best:
  1. Lambdas and closures
  2. Callable classes
  3. Namespaces
  4. The Phar extension
  5. Late static binding
There are some other features beside the above mentioned, but these are easier to present so I'll shortly describe them here:

1. __callStatic

This is just like the __call we all know except it is designed to work when calling methods in a static context:
<?php

class Test
{
public static function __callStatic($method, $args)
{
return array($method, $args);
}
}

var_dump(Test::dummyMethod(
'with dummy argument'));

2. NOWDOC strings

We all know HEREDOC strings and the fact they are parsed by the PHP engine for variable interpolation. They're also good when we have large strings with both single and double quotes, because it saves us from escaping them. Some PHP internals thought though, that the overhead produced for variable interpolation is to big, so they came up with NOWDOC strings. This is just like HEREDOC save for the variable interpolation. Here's an example:
<?php

$here_doc = <<<STR
Some
random string with $variable interpolation...
STR;

$now_doc = <<<'STR'
Some random string without $variable interpolation...
STR;

3. Ternary shortcut (?:)

This is just like the old ternary operator except that we can leave out the middle statement. The rule is that, if the left-hand side expression evaluates to true, its result is returned, otherwise it will return the result of the result of right-hand side expression:
<?php

var_dump(
'' ?: 'there was an empty string');

var_dump(
'I am not empty' ?: 'there was an empty string');

4. Limited goto

Honestly, I don't yet understand why this construct is limited because I have never worked with gotos. All I know is that we cannot use goto statements inside loops, this will cause a fatal error to be thrown. Anyway, here's a basic example taken straight from the manual:
<?php

goto
a;
echo 'Foo';

a:
echo 'Bar';