Search

12/21/2010

Performance Calendar » The new Twitter

Performance Calendar » The new Twitter

URL Routing
Many people have noticed that the new Twitter.com brought a small change to the site’s URL structure: the introduction of a /#!/ at the front of the path. This is a simple change that most front-end engineers are already familiar with, but with huge performance savings. We can track changes in the application state using the URL, but without a new page load. We also get history and back button support in modern browsers, and can update state as the user edits the URL due to HTML5′s new hashchange event. The #! is there to comply with Google’s Ajax crawling specification, so we don’t lose out on search engine rankings with the new scheme.


Getting Started - Making AJAX Applications Crawlable - Google Code

12/13/2010

YUITest Selenium driver

» 命令行方式执行YUITest单元测试 Kejun’s Blog
YUITest Selenium driver wiki
Introducing the New YUI Test » Yahoo! User Interface Blog (YUIBlog)
Install Selenium-RC
Installing Selenium Server

The Selenium-RC server is simply a Java jar file (selenium-server.jar), which doesn’t require any special installation. Just downloading the zip file and extracting the server in the desired directory is sufficient.
Running Selenium Server

Before starting any tests you must start the server. Go to the directory where Selenium-RC’s server is located and run the following from a command-line console.

java -jar selenium-server.jar

Video: Nicholas C. Zakas — YUI Test



step1: install hudson
step2: install seleniumhq plugin
step3: job configuration

java -jar /home/chunghe/yuitest/yuitest-selenium-driver-0.5.5.jar --resultsdir /var/lib/hudson/jobs/yuitest/workspace http://localhost/yui.test.htm

Post-build Actions: select "Publish JUnit test result report" and *.xml

12/12/2010

資深菜鳥的工作雜想 – MMDays

資深菜鳥的工作雜想 – MMDays

我印象很深刻的是在一段YouTube的影片,是比爾蓋茲與華倫巴菲特回到校園的一段訪談,在對於如何快速升遷到高層這個問題上,他們都不約而同回答了到善於與人相處,更甚於是如何在團體前從容的演說,以及如何激發出與你共事者的績效,這是十分罕見的天份,也更是值得馬上立即培養的能力,因為未來的五六十年還是會持續需求這樣的技能。 我十分同意也很深刻感同深受他們這段的對話,我們往往希望自己再聰明一點、專業再強一點,但其實最後成長脫穎而出來的真正關鍵不會是IQ 200,而是那些看似樸實卻是更罕見的能力。 這點的確也印証在職場上,明明許多已經能力出眾的人,最後就往往在與人同事上的問題,或是溝通技巧、表達能力上限制住他在專業領域的傑出表現,在團體戰的現在,沒辦法凝聚眾人的力量完成事情的話,就會被侷限住無法更上一層樓。 另外,這也不僅只是工作,更是人生受益的技能,所以我會極力建議把相關的soft skills列為終生學習的目標。 這裡我只分享一項自己最深刻的體悟,就是學習這些技能最難的部分,不是改變別人,而是改變自己。

12/08/2010

新東南海鮮餐廳@台北

新東南海鮮餐廳@台北

新東南活海鮮餐廳
北市中正區汀州路一段105號
02-23014239

[食記] 四川吳抄手

[食記] 四川吳抄手

四川吳抄手
ADD:台北市忠孝東路四段250號之3
TEL:02-27216088

12/04/2010

jstestdriver


D:\code\js-test-driver>java -jar JsTestDriver-1.2.2.jar --port 1234 --browser "
D:\Program Files\GoogleChromePortable\GoogleChromePortable.exe"



D:\code\js-test-driver>java -jar JsTestDriver-1.2.2.jar --tests all


config:

server: http://localhost:1234

load:
- test/*.js

12/03/2010

TDD, Test driven development

Just a quick refresher, TDD looks like this:

1. Create a test
2. Run all tests, making sure the new test fails
3. Write the minimum amount of code to make the test pass
4. Run all of the tests to ensure they pass
5. Refactor the code, making sure that the tests still pass
6. Repeat for each new code module being developed

The Effectiveness of Test Driven Development (TDD) | GrokCode

11/30/2010

停車入庫



非字形停車位
1. 距離1.5M處


2. 格一個車位的車位中間, 往左打滿, 車頭正時, 馬上打滿


一字形停車位
1. 距離 50cm 處


2. 當右車鏡對準旁車B柱, 向右打滿


3. 當車和旁車夾45度角時, 往左打滿, 繼續倒車

11/27/2010

sproutcore icons

http://demo.sproutcore.com/sample_controls/

11/25/2010

Chicago Pizza Factory Taiwan 芝加哥披薩

Chicago Pizza Factory Taiwan 芝加哥披薩
Chicago Pizza Factory Taiwan
Add : 台北市建國南路二段11巷1號1樓
Tel : 02-2707-2121
營業時間 : 11:00am ~ 8:00pm (全年無休)

11/19/2010

JavaScript Mixins

JavaScript Mixins


var Mixin = function() {};
Mixin.prototype = {
serialize: function() {
var output = [];
for(key in this) {
output.push(key + ': ' + this[key]);
}
return output.join(', ');
}
};



augment(Author, Mixin);

var author = new Author('Ross Harmes', ['JavaScript Design Patterns']);
var serializedString = author.serialize();

11/10/2010

Learning Javascript with Object Graphs - How To Node - NodeJS

Learning Javascript with Object Graphs - How To Node - NodeJS

Backbone.js

Backbone.js


Introduction

When working on a web application that involves a lot of JavaScript, one of the first things you learn is to stop tying your data to the DOM. It's all too easy to create JavaScript applications that end up as tangled piles of jQuery selectors and callbacks, all trying frantically to keep data in sync between the HTML UI, your JavaScript logic, and the database on your server. For rich client-side applications, a more structured approach is helpful.

With Backbone, you represent your data as Models, which can be created, validated, destroyed, and saved to the server. Whenever a UI action causes an attribute of a model to change, the model triggers a "change" event; all the Views that display the model's data are notified of the event, causing them to re-render. You don't have to write the glue code that looks into the DOM to find an element with a specific id, and update the HTML manually — when the model changes, the views simply update themselves.

Backbone.Events

Events is a module that can be mixed in to any object, giving the object the ability to bind and trigger custom named events. Events do not have to be declared before they are bound, and may take passed arguments. For example:

var object = {};

_.extend(object, Backbone.Events);

object.bind("alert", function(msg) {
alert("Triggered " + msg);
});

object.trigger("alert", "an event");

Bind a callback function to an object. The callback will be invoked whenever the event (specified by an arbitrary string identifier) is fired. If you have a large number of different events on a page, the convention is to use colons to namespace them: "poll:start", or "change:selection"

Callbacks bound to the special "all" event will be triggered when any event occurs, and are passed the name of the event as the first argument. For example, to proxy all events from one object to another:


proxy.bind("all", function(eventName) {
object.trigger(eventName);
});

unbind

object.unbind("change", onChange); // Removes just the onChange callback.
object.unbind("change"); // Removes all "change" callbacks.
object.unbind(); // Removes all callbacks on object.

Backbone.Model
Models are the heart of any JavaScript application, containing the interactive data as well as a large part of the logic surrounding it: conversions, validations, computed properties, and access control. You extend Backbone.Model with your domain-specific methods, and Model provides a basic set of functionality for managing changes.

The following is a contrived example, but it demonstrates defining a model with a custom method, setting an attribute, and firing an event keyed to changes in that specific attribute. After running this code once, sidebar will be available in your browser's console, so you can play around with it.

var Sidebar = Backbone.Model.extend({
promptColor: function() {
var cssColor = prompt("Please enter a CSS color:");
this.set({color: cssColor});
}
});
window.sidebar = new Sidebar;
sidebar.bind('change:color', function(model, color) {
$('#sidebar').css({background: color});
});

sidebar.set({color: 'white'});
sidebar.promptColor();



Web applications often choose to change their URL fragment (#fragment) in order to provide shareable, bookmarkable URLs for an Ajax-heavy application. Backbone.Controller provides methods for routing client-side URL fragments, and connecting them to actions and events.

Backbone controllers do not yet make use of HTML5 pushState and replaceState. Currently, pushState and replaceState need special handling on the server-side, cause you to mint duplicate URLs, and have an incomplete API. We may start supporting them in the future when these issues have been resolved.


Backbone.js Tutorial - by noob for noobs

9/27/2010

HTML5 Custom Data Attributes (data-*)

HTML5 Custom Data Attributes (data-*)

Thanks to HTML5, we now have the ability to embed custom data attributes on all HTML elements. These new custom data attributes consist of two parts:

Attribute Name
The data attribute name must be at least one character long and must be prefixed with 'data-'. It should not contain any uppercase letters.
Attribute Value
The attribute value can be any string.

Using data- attributes with JavaScript

// 'Getting' data-attributes using getAttribute
var plant = document.getElementById('strawberry-plant');
var fruitCount = plant.getAttribute('data-fruit'); // fruitCount = '12'

// 'Setting' data-attributes using setAttribute
plant.setAttribute('data-fruit','7'); // Pesky birds


This method will work in all modern browsers, but it is not how data- attributes are intended to be used. The second (new and improved) way to achieve the same thing is by accessing an element’s dataset property. This dataset property — part of the new HTML5 JavaScript APIs — will return a DOMStringMap object of all the selected element's data- attributes. When using this approach, rather than using the full attribute name, you can ditch the data- prefix and refer to the custom data directly using the name you have assigned to it. Data attribute names which contain hyphens will be stripped of their hyphens and converted to CamelCase.


// 'Getting' data-attributes using dataset
var plant = document.getElementById('sunflower');
var leaves = plant.dataset.leaves; // leaves = 47;

// 'Setting' data-attributes using dataset
var tallness = plant.dataset.plantHeight; // 'plant-height' -> 'plantHeight'
plant.dataset.plantHeight = '3.6m'; // Cracking fertiliser

A gentle introduction to CouchDB for relational practitioners

A gentle introduction to CouchDB for relational practitioners



CouchDB is a document-oriented database written in Erlang that addresses a particular “sweet spot” in data storage and retrieval needs. This blog post is an introduction to CouchDB for those of us who have a relational database background.

A CouchDB database doesn’t have tables. It has a collection of documents, stored in a B+Tree. A document is a collection of attributes and values. Values can be atomic, or complex nested structures such as arrays and sub-documents. When you add a document to a database, CouchDB stores it in the B+Tree, indexed by two attributes with special meaning: _id and _rev.

CouchDB lets you store related data together even if it isn’t all the same type of data; you can store documents representing blog posts, users, and comments — all in the same database. This is not as chaotic as it sounds. To get your data back out of CouchDB in sensible ways, you define views over the database. A view stores a subset of the database’s documents. You can think of them as materialized partial indexes. You can create a view of blog posts, and a view of comments, and so on. Each view is another B+Tree. It stays up-to-date with the changes you make to the database.

You can structure your documents any way you want. There is no fixed schema. If you decide after a while that you want to add tags to your blog posts, you can simply write new posts with a collection of tags and save them into the database. Old posts won’t have tags, but that’s OK; if your application code can read the old format and write the new format, you have an application that doesn’t need a fixed schema.

Updates are never done in-place. Everything is copy-on-write. New revisions are saved into the database as new documents, obsoleting old ones, and CouchDB increments the _rev property each time. To update a document, you fetch it, change it, and send it back, specifying the _id and the most recent _rev. If someone else changed the document in the meantime, your _rev is stale, and your update fails. You must re-fetch and re-save; you can’t lock a document.

CouchDB runs on HTTP and JSON. All of its operations, such as store and retrieve, are standard HTTP requests. The documents themselves are represented in JSON. You can talk directly to CouchDB with curl, Ajax, and anything else that can speak HTTP. There is no “protocol” other than this. CouchDB isn’t just Web-friendly, it is actually made of the same technologies that the Web is made of. You query CouchDB by specifying the database, document ID, view name, and so forth directly in the URL. For example, to fetch a blog post document from the “blog” database, you might issue a GET /blog/helloworld. Queries against views and other objects have simple clean URLs, too.

CouchDB uses special documents, called “design documents,” to store JavaScript code in the database. The code defines the views I mentioned earlier. Another thing you can store is validation functions. This is code that CouchDB executes when you save a document to the database. It accepts a document as input, and can reject it, so you do have control over the schema of documents — it doesn’t have to be a free-for-all. In the blog application, you can have a validation function that starts by enforcing “every document must have a ‘type’ property, and its content must be one of (post,user,comment).” Then you can have separate validation logic for each type of document.

Design documents can also contain something called “show functions.” CouchDB will execute the function’s code in response to HTTP requests to that URL, and send the resulting data back as an HTTP response (as usual). With show functions, you can store entire applications inside the database. Your browser might never even know that it’s talking to a database directly, instead of a web server with a database behind it.

CouchDB isn’t designed for arbitrary queries at runtime. You can only query one view, show function, or database at a time. You can’t do joins. You can’t do arbitrary GROUP BY and ORDER BY. You have to decide in advance what operations you’re going to need, and build views for them. You can then issue requests to those views, essentially the equivalent of key lookups and range scans with a few basic options such as an offset, limit, and reverse order. Now, having said that, you can define views that reduce the database down to aggregates, create a custom ordering, and so on. You can define the equivalent of the relational “project” operation inside your view code.

Here’s how: a view is a map-reduce operation. A view is defined in two parts, the map and the reduce. The map is not optional; it generates the contents of the view. It is a JavaScript function. CouchDB iterates over the database and feeds each document into the function, collects the results, and inserts them into the view’s B+Tree index. Inside the view function’s code, you emit key-value 2-tuples.

* The key will identify the tuple in the index that’s built to store this view. It can be simple or complex, so you can create a view that’s keyed by [this,that,the_other_thing]. The view will be ordered by the same thing; that’s how B+Trees work.
* The value you emit is whatever you want the B+Tree to store at its leaf nodes, and can also be complex (it’s a document, like any other).

The “reduce” part of the operation is optional. It computes what is stored in the non-leaf nodes of the B+Tree index. For example, you can use it to create aggregates, such as summing up counts of comments. In addition to the reduce part of the code, there is a “rereduce”. The rereduce is called as the operation is invoked on higher and higher non-leaf nodes, all the way to the root of the tree. CouchDB knows how to take advantage of the data that’s stored by these reduce and rereduce operations, so for example, it doesn’t necessarily have to descend all the way to the leaf nodes and scan in order to count how many documents match a particular query.

An important thing to know about all this code is that nothing is allowed to have side effects. You can’t modify the database in a view definition, for example. Documents are immutable; it’s all copy-on-write. You get input; you can specify output; that’s it, period. It’s a form of functional programming. Why do we care? Because it keeps things simple and elegant, and enables all kinds of nice properties and functionality, such as replication and eventual consistency and cache expiry and scaling to multiple nodes and so on.

The database file is append-only. Old versions don’t automatically get cleaned up. The database grows forever until you compact it. This process builds a new database and then does a swap-and-discard. The append-only, copy-on-write design makes backups easy, and data corruption unlikely.

CouchDB comes with a “graphical user interface” called Futon. It’s built right into the database, and surprise! — it works through HTTP and Ajax. You just fire up CouchDB, point your Web browser to /_utils, and go. It’s a fun way to explore CouchDB.

With all that in mind, why would you want to use CouchDB instead of a relational database? For most things I’m involved with, I want a relational database. But I got asked recently to help with a database that’ll store records about people. Although nobody has implemented anything yet, it’s a terrible match for a relational database, and an excellent fit for a document-oriented one. The inputs are going to be arbitrary documents with different structures, such as census records, birth records, tax records, estate and probate records, marriage records, and so on. Nobody knows what it’s going to store in the future. When people build “flexible schemas” in relational databases, they usually go for the so-called EAV or EBLOB models. In other words, they aren’t using the database relationally at all, and it simply doesn’t work well. This type of project needs a document-oriented database.

I’ve left out a lot of important details, but the point of this post is to understand the high-level CouchDB concepts and how they’re implemented, so you can reason for yourself about it. If you’ve read this far and you think that CouchDB might be a good fit for your needs, I encourage you to take a look at CouchDB, The Definitive Guide.

9/24/2010

Performance of Greedy vs. Lazy Regex Quantifiers

Regular Expressions Cookbook

Problem
Match a pair of <p> and </p> XHTML tags and the text between them. The text between
the tags can include other XHTML tags
Solution
<p>.*?</p>
Take a look at one incorrect solution for the problem in this recipe:
<p>.*</p>
After matching the first <p> tag in the subject, the engine reaches ‹.*›. The dot matches
any character, including line breaks. The asterisk repeats it zero or more times. The
asterisk is greedy, and so ‹.*› matches everything all the way to the end of the subject
text. Let me say that again: ‹.*› eats up your whole XHTML file, starting with the first
paragraph.
When the ‹.*› has its belly full, the engine attempts to match the ‹<› at the end of the
subject text. That fails. But it’s not the end of the story: the regex engine backtracks.
The asterisk prefers to grab as much text as possible, but it’s also perfectly satisfied to
match nothing at all (zero repetitions). With each repetition of a quantifier beyond the
quantifier’s minimum, the regular expression stores a backtracking position. Those are
positions the engine can go back to, in case the part of the regex following the quantifier
fails.
When ‹<› fails, the engine backtracks by making the ‹.*› give up one character of its
match. Then ‹<› is attempted again, at the last character in the file. If it fails again, the
engine backtracks once more, attempting ‹<› at the second-to-last character in the file.
This process continues until ‹<› succeeds. If ‹<› never succeeds, the ‹.*› eventually runs
out of backtracking positions and the overall match attempt fails.
If ‹<› does match at some point during all that backtracking, ‹/› is attempted. If ‹/› fails,
the engine backtracks again. This repeats until ‹</p>› can be matched entirely.
So what’s the problem? Because the asterisk is greedy, the incorrect regular expression
matches everything from the first <p> in the XHTML file to the last </p>. But to correctly
match an XHTML paragraph, we need to match the first <p> with the first </p> that
follows it.
That’s where lazy quantifiers come in. You can make any quantifier lazy by placing a
question mark after it: ‹*?›, ‹+?›, ‹??›, and ‹{7,42}?› are all lazy quantifiers.

Lazy quantifiers backtrack too, but the other way around. A lazy quantifier repeats as
few times as it has to, stores one backtracking position, and allows the regex to continue.
If the remainder of the regex fails and the engine backtracks, the lazy quantifier
repeats once more. If the regex keeps backtracking, the quantifier will expand until its
maximum number of repetitions, or until the regex token it repeats fails to match.


Performance of Greedy vs. Lazy Regex Quantifiers
Consider the following simple example: When the regexes <.*?> and <[^>]*> are applied to the subject string "<0123456789>", they are functionally equivalent. The only difference is how the regex engine goes about generating the match. However, the latter regex (which uses a greedy quantifier) is more efficient, because it describes what the user really means: match the character "<", followed by any number of characters which are not ">", and finally, match the character ">". Defined this way, it requires no backtracking in the case of any successful match, and only one backtracking step in the case of any unsuccessful match. Hand-optimization of regex patterns largely revolves around the ideas of reducing backtracking and the steps which are potentially required to match or fail at any given character position, and here we've reduced both cases to the absolute minimum.


jQuery Regular Expressions Review (Rev:20100921_1700)
/color|date|datetime|email|hidden|month|number|
password|range|search|tel|text|time|url|week/i
/\b(?:color|date|datetime|email|hidden|month|number|
password|range|search|tel|text|time|url|week)/i
In a manner similar to the previous example, adding (or "exposing") a word boundary anchor to the beginning of this regex improves the efficiency in the case of non-matches, by reducing the number of positions within the string where the regex engine attempts a match. Instead of attempting a match at every location within a target string, the engine now only needs to check on word boundaries.

9/19/2010

pdf crop

新的 6 吋 Kindle 發表了(Kindle 3) - Mobile01 討論群組

關於用 Kindle DX 來看 PDF,有多餘白色區域的部份,
我是用 A-PDF Page Crop 3.4 這個程式,這雖然是要錢的,
但去下載試用版也只是在第一頁會加浮水印,其他頁面沒有影響,
也沒看它有時間限制。


SourceForge.net: briss
This project was registered on SourceForge.net on May 4, 2010, and is described by the project team as follows:

This project aims to offer a simple cross-platform application for cropping PDF files. A simple user interface lets you define exactly the crop-region by fitting a rectangle on the visually overlaid pages.

9/13/2010

Microdata: HTML5’s Best-Kept Secret

Microdata: HTML5’s Best-Kept Secret


<div itemscope itemtype="http://data-vocabulary.org/Organization">
<h1 itemprop="name">Hendershot's Coffee Bar</h1>
<p itemprop="address" itemscope itemtype="http://data-vocabulary.org/Address">
<span itemprop="street-address">1560 Oglethorpe Ave</span>,
<span itemprop="locality">Athens</span>,
<span itemprop="region">GA</span>.
</p>
</div>


The Microdata markup adds a couple attributes you may not have seen before, itemscope, itemtype and itemprop. The first is essentially just a top level marker, it tells the search engine spider that you’re about to define something in the following nested tags. The itemtype attribute tells the spider what you’re defining — in this case, an organization.

The rest of the markup should look pretty familiar if you’ve used Microformats. The main change is the itemprop attribute (short for item property) to define what each element is. Because our address is all one paragraph, we’ve added some span tags to define each element of the address separately — street address, locality and so on. If we wanted, we could add other properties like a phone number (itemprop="tel"), a URL (itemprop="url") or even geodata (itemprop="geo").

So where did we get these itemprop vocabularies from? Well, as the URL in the itemtype attribute indicates, they come from data-vocabulary.org. Of course you can make up your own itemprop syntax, but if you want search engine spiders to understand your microdata, you’re going to have to document what you’re doing. Since the definitions at data-vocabulary.org cover a number of common use cases — events, organizations, people, products, recipes, reviews — it makes a good starting point.

Microformats and RDFa
Actually, the reasoning seems to have been something like this: Microformats are a really good idea, but essentially a hack. Because Microformats rely only on the class and rel attributes, writing parsers to read them is complicated.

At the same time, RDFa was designed to work with the now-defunct XHTML 2.0 spec. Although RDFa is being ported to work with HTML5, it can be overly complex for many use cases. RDFa is a bit like asking what time it is and having someone tell you how to build a watch. Yes, RDFa can do the same things HTML5 microdata and Microformats do (and more), but if the history of the web teaches us a lesson, it’s that simpler solutions almost always win.


google - 複合式摘要與結構化標記 - 網站管理員工具說明

* Using Microformats in HTML5
* Where on the Web Is HTML5?
* Add Semantic Value to Your Pages With HTML 5
* Microformats are Awesome, Now Put Them to Work for Your Site

9/10/2010

yui synchronousCall


function synchronousCall() {
var args = [].slice.call(arguments);
var iter = function (args) {
var fn = args.shift();
if (fn && fn.call()) { // return true means no ajax call is made, excute next
iter(args);
}
};

iter(args);

Connect.completeEvent.subscribe(function (type, data, args) {
console.log('completeVent', args)
iter(args);
}, args);
}

Internet Explorer Developer Toolbar


Internet Explorer Developer Toolbar

creating, understanding, and troubleshooting Web pages.
6/7/2010

9/06/2010

align checkboxes, radios, text inputs with their label

/* align checkboxes, radios, text inputs with their label
by: Thierry Koblentz tjkdesign.com/ez-css/css/base.css */
input[type="radio"] { vertical-align: text-bottom; }
input[type="checkbox"] { vertical-align: bottom; *vertical-align: baseline; }
.ie6 input { vertical-align: text-bottom; }


via: http://html5boilerplate.com/

matchit.zip - extended % matching for HTML, LaTeX, and many other languages : vim online

matchit.zip - extended % matching for HTML, LaTeX, and many other languages : vim online

把玩 C 語言的時候利用 % 指令在括弧間跳躍是相當爽的,安裝這鬼玩意後,html的tag也可以 % 跳躍了 #ifdef #endif 也可以用 % 跳躍了..

9/05/2010

Media queries

Media queries

Media queries consist of a media type and one or more expressions, involving media features, which resolve to either true or false. The result of the query is true if the media type specified in the media query matches the type of device the document is being displayed on and all expressions in the media query are true.


media_query_list: [, ]*
media_query: [[only | not]? [ and ]*]
| [ and ]*
expression: ( [: ]? )
media_type: all | aural | braille | handheld | print |
projection | screen | tty | tv | embossed
media_feature: width | min-width | max-width
| height | min-height | max-height
| device-width | min-device-width | max-device-width
| device-height | min-device-height | max-device-height
| aspect-ratio | min-aspect-ratio | max-aspect-ratio
| device-aspect-ratio | min-device-aspect-ratio | max-device-aspect-ratio
| color | min-color | max-color
| color-index | min-color-index | max-color-index
| monochrome | min-monochrome | max-monochrome
| resolution | min-resolution | max-resolution
| scan | grid


CSS Media Queries: Bees Knees Or Spawn of Satan?

<link rel="stylesheet" type="text/css"
media="screen and (max-device-width: 480px)"
href="shetland.css" />

Responsive Web Design

http://caniuse.com/

http://caniuse.com/

Professional JavaScript

Professional JavaScript

functional libraries
* Underscore.js http://documentcloud.github.com/underscore/
* Functional JavaScript http://osteele.com/sources/javascript/functional/

remove spacing for firefox inline-block elements

http://yuiblog.com/sandbox/yui/3.2.0pr1/build/cssgrids/grids.css


.yui3-g {
letter-spacing: -0.31em; /* webkit: collapse white-space between units */
*letter-spacing: normal; /* reset IE < 8 */
word-spacing: -0.43em; /* IE < 8 && gecko: collapse white-space between units */
}

cleaner:

<ul><li>
stuff...
</li><li>
more stuff
</li><li>
ok, enough stuff, already.
</li></ul>

sample: http://chunghe.googlecode.com/svn/trunk/experiment/inline-block/inline-block-firefox.htm

CSS inline/block nuances
White Space Collapsing: the 'white-space-collapse' property - it hasn't been implemented by any vendor as of yet.

9/02/2010

[美食] 台北東區。傑夫的燒肉 @ Masako的抹茶福氣家 :: 痞客邦 PIXNET ::

[美食] 台北東區。傑夫的燒肉 @ Masako的抹茶福氣家 :: 痞客邦 PIXNET ::

地址:忠孝東路四段170巷6弄7號
(忠孝敦化捷運站5號出口,神旺飯店正後方巷子)

電話:02-27735985
價位:399 / 499 (部份菜色不同) 開幕期間免加1成服務費,之後不確定

8/19/2010

The Clean Coder: Why Clojure?

The Clean Coder: Why Clojure?a

I have recently become quite an enthusiast for the language Clojure. But why? Why would someone who has spent the last 30 years programming in C, C++, Java, C#, and Ruby suddenly become enamored with a language that has roots that go back to 1957, i.e. Lisp?

During my first few decades as a professional programmer, I never learned Lisp. I had heard of it, of course; though mostly in derisive terms. People sneered about it with names like "Lots of InSignificant Parentheses". So my view was not particularly favorable.

A few years ago, someone suggested that I learn Lisp by reading a book entitled: "The Structure and Interpretation of Computer Programs". So I went to Amazon and ordered a copy from the used books section. It arrived a week or so later, and then sat on my "to read" stack for a couple of years.

I started reading it about two years ago; and it changed everything I had previously felt and believed about Lisp. It also changed a great deal of what I felt and believed about programming in general. In short, the book was startling.

SICP is a literary masterpiece. It's not often that you can say that a technical book is a page-turner, but that's just what I found SICP to be. The book moves from topic to topic with rare ease and clarity, but more importantly it moves with purpose and mission. As you read it, you can feel the authors slowly building a tension towards a climax. The chapters fly by as you read about data structures, algorithms, message passing, first-class procedures, and so much else. Each concept leads inevitably to the next. Each chapter adds to the ever building tension. By time you are half-way through the book, the sense that something important is about to change becomes palpable.

And then something important changes! Something you had not anticipated. Something you should have guessed, but did not. On page 216 they introduce a concept so familiar that most programming books start with it. On page 216 they prove to you that you've had some wrong ideas about programming all along. On page two hundred and sixteen, after talking about algorithms, data structures, recursion, iteration, trees, high-order procedures, scoping, local variables, data abstraction, closures, message-passing, and a plethora of other topics -- after all that, they introduce assignment!

And with that elegant coup-de-grace (which is not the last in this book!), they vanquish the concept that programming is about manipulating state. With that one stroke, they force you to look back on all you had done in the previous pages in a new and enlightened way -- a functional way.



If you've ever written multi-threaded code, the thought of eight, sixteen, thirty-two, or even more processors running your program should fill you with dread. Writing multi-threaded code correctly is hard! But why is it so hard? Because it is hard to manage the state of variables when more than one CPU has access to them.

And this is where functional programming comes in. Functional programming, of the kind shown in SICP, is a way to write code that does not manage the state of variables, and could therefore be partitioned to run in parallel on as many processors as you like -- at least in theory. In practice it might not be quite that trivial; but one thing is certain. Moving functional programs to massively parallel system will be easier than moving non-functional programs.

Why Clojure?
So why is Clojure the best option for a functional language? After all, there are lots of functional languages out there. Some are old, like Haskell, and Erlang. Some are new like Scala and F#. Why is Clojure the language that has everybody so fired up? Here are just a few reasons.

* Clojure is Lisp. And Lisp is a functional, simple, well-known, elegant language. The syntax is almost laughably terse. This is in contrast to languages like F# and Scala which have a complexity and "quirkiness" reminiscent of C++.
* Clojure is Java. Clojure sits on top of the Java stack, and has the ability to inter-operate with Java with extreme ease. Java programs can call Clojure, and Clojure can call Java. You can write Clojure code that derives from Java classes and overrides Java methods. In short, if you can do it in Java, you can do it in Clojure. What's more there is a Clojure port for the CLR! So Clojure may be the only functional language that inter-operates well with both major VMs.
* Clojure implements Software Transactional Memory which means that any time a Clojure programmer want's to change the state of a variable, they must do so using the same kind of transaction management as they would use for a database. This enforces the functional paradigm do a degree that few other functional languages do. The STM facilities of Clojure are elegant and simple, just like the rest of the language. They do not intrude where they aren't needed, and they are simple to employ where state must be changed.

* Clojure is fast. Data structures in functional languages are immutable. For example, you can't add an item to a list, instead you create a copy of the list with the new item added. This copying could obviously slow things down a lot. Clojure manages complex immutable data structures using a sharing technique that eliminates the need to make deep copies of those structures. This means that Clojure runs very fast.
* Clojure is supported. There are tutorials and blogs. There are IDE plugins. And there are mailing lists and user groups. If you program in Clojure, you won't be alone.

【costco】Lysol 馬桶清潔劑

【costco】Lysol 馬桶清潔劑
Clorox馬桶漂白錠,6顆裝$299

CSS pointer-events to allow clicks on underlying elements

CSS pointer-events to allow clicks on underlying elements
demo


.overlay {
position: absolute;
right: 0px;
top: 0;
width: 40px;
height: 40px;
background: rgba(0, 0, 0, 0.5);
}
.pointer-events-none {
pointer-events: none;
}

8/11/2010

Vim 80 column layout concerns

Vim 80 column layout concerns


function HightLightOverLength()
highlight OverLength ctermbg=darkred ctermfg=white guibg=#FFD9D9
match OverLength /\%>80v.\+/
endfunction

map <F12> :call HightLightOverLength()

vim: jsbeautify : a javascript source code formatter

jsbeautify : a javascript source code formatter

Vim 的 JavaScript 縮排格式最佳化 外掛

1. 於此 jsbeautify : a javascript source code formatter 下載 jsbeautify.vim
2. mkdir -p ~/.vim/plugin
3. mv jsbeautify.vim ~/.vim/plugin/
4. vim .vimrc # 設定 鍵值 (若已經有設好 鍵, 此步驟請跳過)
let mapleader=","
5. ,ff # 直接 ,ff 就可以顯示格式化縮排的結果

vim colorscheme: zenburn

With sufficient thrust, pigs fly just fine. » Zenburn

To use Zenburn in Vim, you must enable the 256-color mode for Vim. This can be done with e.g. export TERM=xterm-256color. You might also need to add set t_Co=256 into your .vimrc file, before loading the colorscheme. Note, that due to limitations of the 256-color mode the color scheme is not exactly like it appears in GVim, but very close nevertheless.

Tweaking Vim For Fun and Profit
tput colors

8/10/2010

清新純淨~WeiB

清新純淨~WeiB

電話:(02)2732-5099
地址:台北市安和路2段71巷6號1樓
官網:http://www.weis.com.tw/index.htm

L’IDIOT 驢子餐廳

L’IDIOT 驢子餐廳

L’IDIOT 驢子餐廳
地址:台北市民生東路三段156號1樓
電話:02-25456966
網站:http://www.lidiotrestaurant.com

8/09/2010

IE的transparent border

CSS Border使用小分享

- 透明:
IE6浏览器不支持transparent透明属性,就border生成三角技术而言,直接设置对应的透明边框的border-style属性为 dotted或是dashed即可解决这一问题,原因是在IE6下, 点线与虚线均以边框宽度为基准,点线长度必须是其宽度的3倍以上(height>=border-width*3),虚线宽长度必须是其宽度的5倍以上(height>=border-width*5),否则点线和虚线都不会出现.
- IE6的奇偶bug:
如果定位外框高度或是宽度为奇数,则IE6下,绝对定位元素的低定位和右定位会有1像素的误差.所以,尽量保证外框的高度或宽度为偶数值.
- IE6的空div高度bug:
IE6下,空div会有莫名的高度,也就是说height:0;不顶用,此时形成的尖角的实际占高于其他浏览器是有差异的.可使用font-size:0; + overflow:hidden;修复此问题.
- filter: chroma滤镜
该属性属性可以设置一个对象中指定的颜色为透明色, 如:

border-color: pink;
filter: chroma(color=pink);


via: Creating Triangle Arrows in pure CSS

demo: http://chunghe.googlecode.com/svn/trunk/experiment/border.slants/ie-transparent-border.html

8/05/2010

Dynamically removing/ replacing an external JavaScript or CSS file

Dynamically removing/ replacing an external JavaScript or CSS file

So what actually happens when you remove an external JavaScript or CSS file? Perhaps not entirely what you would expect actually. In the case of JavaScript, while the element is removed from the document tree, any code loaded as part of the external JavaScript file remains in the browser's memory. That is to say, you can still access variables, functions etc that were added when the external file first loaded (at least in IE7 and Firefox 2.x). If you're looking to reclaim browser memory by removing an external JavaScript, don't rely on this operation to do all your work. With external CSS files, when you remove a file, the document does reflow to take into account the removed CSS rules, but unfortunately, not in IE7 (Firefox 2.x and Opera 9 do).

Notice the helper function createjscssfile(), which is essentially just a duplicate of loadjscssfile() as seen on the previous page, but modified to return the newly created element instead of actually adding it to the page. It comes in handy when parentNode.replaceChild() is called in replacejscssfile() to replace the old element with the new. Some good news here- when you replace one external CSS file with another, all browsers, including IE7, will reflow the document automatically to take into account the new file's CSS rules.

快速做好重灌隨身碟,歷代Windows全支援


快速做好重灌隨身碟,歷代Windows全支援

* 軟體名稱:WinToFlash 0.6beta
* 官方網站:http://wintoflash.com/home/en/
* 下載網址:按我下載
* 檔案大小:6.7 MB
* 更新日期:2010年7月20日
* 使用限制:無(Freeware)

7/28/2010

My Google Interview ~ C for Coding

Steve Yegge’s Get that job at Google.


The first problem I encountered was that at least two of my interviewers had only passing or no familiarity with Java. This made it particularly difficult as some concepts are unique to one language.

But everyone knew C++. I’ve read about this before. This combined with my own experience now leads me to believe that C++ isn’t optional for any Google applicant. Not because you need to use it to work there. I have no direct experience of this. But because of “interviewer lottery”. Some at Google (it seems) do nothing but C++. You might be interviewed by one of these people.

I had to write several code segments on a whiteboard. This I expected and was fine with. I realize this is necessary (see Why Can't Programmers.. Program? and The Non-Programming Programmer) and have no problem with it but it depends on what kind of problem you ask. Simple is usually best.

Two of the problems I had were extremely finnicky to solve. In one I think the interviewer was understanding and simply wanted to determine if I understand the relevant contract and I could see what the issues were more than coding a completely correct solution (which I appreciated). Another interview got caught short before an efficient solution could be developed and I really don’t think it’s the kind of problem that lends itself to writing a code solution in 40 minute. By this I mean I believe it would be more valuable to speak about the algorithms and problems involved as the code for an efficient solution would be quite complex.

The theme of problem solving and analyzing thought processes remained constant throughout.

For some reason I had expected there would be a lunch break (10-2). There wasn’t. By the end I was mentally exhausted, 3pm (it ran over time) and I hadn’t eaten since the day before. The next day I returned home.

Go through sample interview questions for Google, Microsoft, Amazon and other companies (really - any of them work - they all ask very similar if not the same questions). CareerCup has thousands of these questions (shameless, plus I know :)).
The Official CareerCup Book: Cracking the Coding Interview, 4th Edition

7/27/2010

H-1B visa

Temporary Workers

H-1B Persons in Specialty Occupation which requires the theoretical and practical application of a body of highly specialized knowledge requiring completion of a specific course of higher education. (65,000). This category also includes fashion models and Government-to-Government research and development, or co-production projects administered by the Department of Defense (100);

via: My Google Interview ~ C for Coding

SWIG Tutorial

SWIG Tutorial

SWIG is a software development tool that connects programs written in C and C++ with a variety of high-level programming languages. SWIG is used with different types of languages including common scripting languages such as Perl, PHP, Python, Tcl and Ruby. The list of supported languages also includes non-scripting languages such as C#, Common Lisp (CLISP, Allegro CL, CFFI, UFFI), Java, Lua, Modula-3, OCAML, Octave and R. Also several interpreted and compiled Scheme implementations (Guile, MzScheme, Chicken) are supported. SWIG is most commonly used to create high-level interpreted or compiled programming environments, user interfaces, and as a tool for testing and prototyping C/C++ software. SWIG can also export its parse tree in the form of XML and Lisp s-expressions. SWIG may be freely used, distributed, and modified for commercial and non-commercial use.


So you want to get going in a hurry? To illustrate the use of SWIG, suppose you have some C functions you want added to Tcl, Perl, Python, Java and C#. Specifically, let's say you have them in a file 'example.c'

/* File : example.c */
double My_variable = 3.0;

int fact(int n) {
if (n <= 1) return 1;
else return n*fact(n-1);
}

int my_mod(int x, int y) {
return (x%y);
}

char *get_time()
{
time_t ltime;
time(<ime);
return ctime(<ime);
}


Interface file
Now, in order to add these files to your favorite language, you need to write an "interface file" which is the input to SWIG. An interface file for these C functions might look like this :

/* example.i */
%module example
%{
/* Put header files here or function declarations like below */
extern double My_variable;
extern int fact(int n);
extern int my_mod(int x, int y);
extern char *get_time();
%}

extern double My_variable;
extern int fact(int n);
extern int my_mod(int x, int y);
extern char *get_time();

Building a Tcl module
At the UNIX prompt, type the following (shown for Linux, see the SWIG Wiki Shared Libraries page for help with other operating systems):

unix % swig -tcl example.i
unix % gcc -fpic -c example.c example_wrap.c \
-I/usr/local/include
unix % gcc -shared example.o example_wrap.o -o example.so
unix % tclsh
% load ./example.so example
% puts $My_variable
3.0
% fact 5
120
% my_mod 7 3
1
% get_time
Sun Feb 11 23:01:07 1996

The swig command produces a file example_wrap.c that should be compiled and linked with the rest of the program. In this case, we have built a dynamically loadable extension that can be loaded into the Tcl interpreter using the 'load' command.

Python at Google (Greg Stein - SDForum) [panela.blog-city.com]

Python at Google (Greg Stein - SDForum) [panela.blog-city.com]

Swig is your friend
Google makes extensive use of Swig. Greg indicated that Swig has improved much in recent years. All C++ projects in Google have swig generators created during build time, so python programmers can take advantage of this work. Greg said that neither Boost nor ctypes were as direct or clean as using SWIG.

RPC
RPC is the method Google uses to scale horizontally so well. They have their own internal binary wire format that speaks over http. Programmers can easy speak this format using Java, C++ or Python. Using RPC allows Google to divide computing problems up across large numbers of servers.

Python at Google
Python programmers at Google must follow a strict style guideline (based on PEP8 with 2 spaced indenting). When engineers are first granted commit access to their SCM system, they must pass a style test. All code must pass through two sets of eyes before being checked in. That combined with liberal doses of unittest, pychecker and code coverage eliminates most non-algorithmic issues that might appear in python code.

Where is Python used?
* The Google build system is written in python. All of Google's corporate code is checked into a repository and the dependency and building of this code is managed by python. Greg mentioned that to create code.google.com took about 100 lines of python code. But since it has so many dependencies, the build system generated a 3 megabyte makefile for it!
* Packaging. Google has an internal packaging format like RPM. These packages are created using python.
* Binary Data Pusher. This is the area where Alex Martelli is working, on optimizing pushing bits between thousands of servers
* Production servers. All monitoring, restarting and data collection functionality is done with python
* Reporting. Logs are analyzed and reports are generated using Python.
* A few services including code.google.com and google groups. Most other front ends are in C++ (google.com) and Java (gmail). All web services are built on top of a highly optimizing http server wrapped with SWIG.

7/26/2010

南北貨俱樂部-電冰箱的菜櫥子 - 台式肉燥+黑白魯

南北貨俱樂部-電冰箱的菜櫥子 - 台式肉燥+黑白魯

材料:
1.豬油(絞肉)約2~3斤。沒有豬油可以挑肥一點絞肉效果會比較好。
2.油蔥酥約70克。(類似冰箱買的小包裝兩包)
3.黑豆蔭油約200c.c.。
4.冰糖適量。
5.粉腸一斤、豆干、雞蛋等等隨喜。
6.米酒兩瓶。

1.鍋燒熱後,將豬絞肉下鍋炒。
2.等到肉炒到變白後,加入醬油一起炒。
3.接著,加入冰糖以及油蔥酥,攪拌均勻。
4.最後,加入兩瓶米酒,煮沸後轉小火續魯。
5.大約滾約10分鐘後,將其他要魯的食材放下去一起魯。
6.以小火大概魯個50分鐘之後,台式肉燥黑白魯就大功告成囉。

食譜: 烤地瓜

DIY 烤出專業級香噴噴地瓜

步驟一:把地瓜洗淨後放進冰箱冷凍庫,凍45分鐘。
步驟二:將冷凍後地瓜放進烤箱(200度),烤30分鐘。
專家說~~~
『因為蕃薯冷凍後內水份子變大,破壞纖維密度,並將空氣擠壓,熱傳導加速,可以節省60﹪的烤薯時間,內外熟食度也比較柔軟均勻喔!』


通常購買時會選擇小的或長條型的地瓜,因為家裡是小烤箱,這樣比較不怕高度太高容易烤焦喔!

烤出的地瓜,皮與肉已剝離,撕開外皮後,會有一層QQ的表皮,偶帶焦香,偶帶蜜。

7/14/2010

HTML5 structure—div, section & article ・ @boblet

HTML5 structure—div, section & article ・ @boblet

1. <div>—the "generic flow container" we all know and love. It’s a block-level element with no additional semantic meaning (W3C:Markup, WhatWG)
2. <section>—a "generic document or application section". A <section> normally has a heading (title) and maybe a footer too. It’s a chunk of related content, like a subsection of a long article, a major part of the page (eg the news section on the homepage), or a page in a webapp’s tabbed interface. (W3C:Markup, WhatWG)
3. <article>—an "an independent part of a document or site". This means it should be able to ‘stand alone’, and still make sense if you encountered it somewhere else (eg in an RSS feed). Examples include a weblog article (duh), a forum post or a comment. Like <section> these generally have a header, and maybe a footer (W3C:HTML, WhatWG)

The new HTML5 <section> element is similar to <div> as a general container element, but it *does* have some semantic meaning—the things it contains are a logical group of related content:

The section element represents a generic document or application section. A section, in this context, is a thematic grouping of content, typically with a header, possibly with a footer.


The section element | HTML5 Doctor


# Don’t use it just as hook for styling or scripting; that’s a div
# Don’t use it if article, aside or nav is more appropriate
# Don’t use it unless there is naturally a heading at the start of the section
# The revised spec (as of 16 September) says:
Authors are encouraged to use the article element instead of the section element when it would make sense to syndicate the contents of the element.

As blogposts and comments are often syndicated (by being pulled into other blogs or being linked via twitter, reddit etc) they should be articles.

如何選擇用哪些軟體來開啟/編輯檔案?來試試「開啟專家」吧! | ㊣軟體玩家

如何選擇用哪些軟體來開啟/編輯檔案?來試試「開啟專家」吧! | ㊣軟體玩家

版本:OpenExpert 1.40 (649KB) (個人/家庭使用免費)
官方網站: http://www.baxbex.com/openexpert.html
下載點:http://www.baxbex.com/files/openexp.exe

7/11/2010

Acer Aspire 3810T 灌 XP

1. 到 bios 把硬碟改成 IDE mode
2. 安裝 winxp
3. 按照 分享 解决 Acer Aspire 3810T 灌 XP 时 AHCI 问题 安裝 ACHI driver

1. 先将原本的 Vista 系统 recovery disk 做起来,Acer 网站上提供的 dirver 下载完整,储存起来。
2. 先在 BIOS 将硬碟先设为 IDE 模式,然后安装 XP(因为没有光碟机,我是用随身碟安装 XP SP3,相关准备及设定请参考debbiejames的文章 http://www.mobile01.com/topicdetail.php?f=159&t=665722&p=1
3. 安装 Acer 提供的各项 driver, 其中会发现 "进阶主机控制器介面 Intel SATA AHCI Driver 8.8.0.1009" 执行时会出现 "本系统不符合安装此软体的最低需求,安装程式即将结束" 的错误讯息,这时先不要关闭这个视窗!
4. 接着按 开始 --> 设定 --> 控制台 --> 系统 --> 硬体 --> 装置管理员 , 打开 "IDE ATA/ATAPI 控制器" 项目。
5. 应该会看到 "Intel(R)ICH9M-E/M SATA IDE Controller ",指着它按右键,选 "更新驱动程式" --> "从清单或特定位置安装" --> "不要搜寻,我将选择要安装的驱动程式" --> "从磁片安装" --> 按 "浏览" 将路径指向 C:\Windows\Temp\IIF2\Winall\Driver\iaAHCI.inf
6. 选择对应的硬碟控制器 " Intel(R)ICH9M-E/M SATA AHCI Controller ",在最后面。
7. 按 "下一步" 后 重新开机过程中到 BIOS 内把 硬碟的 AHCI 模式调回来。

4. 到 bios 把硬碟給回 AHCI mode

via: Acer Timeline 3810T 安裝完XP 所發生的問題 - Mobile01 討論群組

7/05/2010

node.js


var sys = require('sys')
filename = process.ARGV[2],
spawn = require('child_process').spawn;

if (!filename)
return sys.puts("Usage: node watcher.js filename");

// Look at http://nodejs.org/api.html#_child_processes for detail.
var tail = spawn("tail", ["-f", filename]);
sys.puts("start tailing");

tail.stdout.addListener("data", function (data) {
sys.puts(data);
});

// From nodejs.org/jsconf.pdf slide 56
var http = require("http");

http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'text/plain'});
tail.stdout.addListener("data", function (data) {
response.write(data);
});
//response.end('Hello World\n');
}).listen(8124);

root@core:~# echo 'line 10' >> foo

6/27/2010

The ``Clockwise/Spiral Rule''

The ``Clockwise/Spiral Rule''

There is a technique known as the ``Clockwise/Spiral Rule'' which enables any C programmer to parse in their head any C declaration!

There are three simple steps to follow:

1. Starting with the unknown element, move in a spiral/clockwise direction; when ecountering the following elements replace them with the corresponding english statements:

[X] or []
=> Array X size of... or Array undefined size of...
(type1, type2)
=> function passing type1 and type2 returning...
*
=> pointer(s) to...

2. Keep doing this in a spiral/clockwise direction until all tokens have been covered.

3. Always resolve anything in parenthesis first!

Example #1: Simple declaration

+-------+
| +-+ |
| ^ | |
char *str[10];
^ ^ | |
| +---+ |
+-----------+

Question we ask ourselves: What is str?

``str is an...

* We move in a spiral clockwise direction starting with `str' and the first character we see is a `[' so, that means we have an array, so...

``str is an array 10 of...

* Continue in a spiral clockwise direction, and the next thing we encounter is the `*' so, that means we have pointers, so...

``str is an array 10 of pointers to...

* Continue in a spiral direction and we see the end of the line (the `;'), so keep going and we get to the type `char', so...

``str is an array 10 of pointers to char''

* We have now ``visited'' every token; therefore we are done!

http://cdecl.org/

6/24/2010

Getting started with node.js on Windows | Lazycoder

Getting started with node.js on Windows | Lazycoder
1. download vmware player. (網路設定改為NAT)
2. download TurnKey Core (102MB VM)
3. apt-get update; apt-get install build-essential; apt-get install git; apt-get install git-core; apt-get install curl; apt-get install vim;
4. ssh root@xxx.xxx.xxx.xxx:22

for ubuntu:
apt-get install libssl-dev
apt-get install pkg-config

6/23/2010

When you overwrite the prototype, it is a good idea to reset the constructor property.

When you overwrite the prototype, it is a good idea to reset the constructor property.
* constructor.prototype.constructor will point to the constructor itself.


function Dog() {
this.tail = true;
}
Dog.prototype.say = function () {
return 'Woof!'
}

var benji = new Dog();
console.log(benji.constructor.prototype.constructor); // Dog {}

// completely replace the prototype object,
// new objects create from now on will use the updated prototype.
Dog.prototype = {paws:4, hair:true};

var lucy = new Dog();

console.log(benji.__proto__); // Object {}
console.log(lucy.__proto__); // Object {paws=4, hair=true}

console.log(typeof benji.paws); // undefined
console.log(typeof benji.say); //function
console.log(typeof benji.paws); // undefined

// the constructor property of the new objects no longer reports correctly.
console.log(lucy.constructor); // Object()
console.log(benji.constructor); // Dog()

// to fix it.
Dog.prototype.constructor = Dog;


var F = function() {}, i;
F.prototype=superc.prototype;
subc.prototype=new F(); // rewrite the prototype.
subc.prototype.constructor=subc; // <--
subc.superclass=superc.prototype;


The prototype chain is live with the exception of when you completely replace the prototype object

function Dog(){this.tail = true;}
var benji = new Dog();
var rusty = new Dog();
Dog.prototype.say = function(){return 'Woof!';}

// completely overwrite the prototype
Dog.prototype = {paws: 4, hair: true};

// It turns out that our old objects do not get access to the new prototype's properties; they still keep the secret link pointing to the old prototype object:
console.log(typeof benji.paws); // undefined
console.log(benji.say()); // Woof!
console.log(typeof benji.__proto__.say); // function
console.log(typeof benji.__proto__.paws); // undefined

var lucy = new Dog();
lucy.say(); // TypeError: lucy.say is not a function
console.log(lucy.paws); // 4
console.log(typeof lucy.__proto__.say); // undefined
console.log(typeof lucy.__proto__.paws); // number


// Now the constructor property of the new objects no longer reports correctly. It should point to Dog(), but instead it points to Object()
lucy.constructor // Object()
benji.constructor // Dog()

// The most confusing part is when you look up the prototype of the constructor
console.log(typeof lucy.constructor.prototype.paws) // undefined
console.log(typeof benji.constructor.prototype.paws) // number

6/18/2010

opensearch

https://developer.mozilla.org/en/Creating_OpenSearch_plugins_for_Firefox
OpenSearch description file


<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/"
xmlns:moz="http://www.mozilla.org/2006/browser/search/">
<ShortName>engineName</ShortName>
<Description>engineDescription</Description>
<InputEncoding>inputEncoding</InputEncoding>
<Image width="16" height="16" type="image/x-icon">data:image/x-icon;base64,imageData</Image>
<Url type="text/html" method="method" template="searchURL">
<Param name="paramName1" value="paramValue1"/>
...
<Param name="paramNameN" value="paramValueN"/>
</Url>
<Url type="application/x-suggestions+json" template="suggestionURL"/>
<moz:SearchForm>searchFormURL</moz:SearchForm>
</OpenSearchDescription>


Autodiscovery of search plugins

<link rel="search" type="application/opensearchdescription+xml" title="MySite: By Author" href="http://www.mysite.com/mysiteauthor.xml">
<link rel="search" type="application/opensearchdescription+xml" title="MySite: By Title" href="http://www.mysite.com/mysitetitle.xml">

6/17/2010

YUI 3 学习笔记:oop - 岁月如歌

YUI 3 学习笔记:oop - 岁月如歌

简析 Extjs 类继承 - { focus : web } - JavaEye技术网站


function A() {
alert('a');
}
function B() {
B.superclass.constructor.call(this);
}
function temp() {
}
temp.prototype = A.prototype;

//防止A 的实例属性也搞到 B 里去 ,没有意思,我们只需要 A 的 prototype 里的公共属性
//不能使用 B.prototype=A.prototype 这样的话修改 B.prototype 则 A.prototype 也变了,以及影响instanceof
//不建议 B.prototype =new A() ;这样的话 A 的实例方法也到 B.prototype 里去了
B.prototype = new temp();

//上一步后 B 的实例的构造函数属性为 A 了,
// B.prototype.constructor == A
//为了以后方便B的子类调用B的构造函数
//如 C.superclass.constructor.call(this);
//要纠正
//B 的实例 的 构造函数属性要设为 B
B.prototype.constructor = B;

//要记录 B 的父亲,便于以后调用父亲方法
B.superclass = A.prototype;

if (A.prototype.constructor == Object.prototype.constructor) {
A.prototype.constructor = A;
}

6/04/2010

John Resig - How JavaScript Timers Work

John Resig - How JavaScript Timers Work


(Click to view full size diagram)

Since JavaScript can only ever execute one piece of code at a time (due to its single-threaded nature) each of these blocks of code are "blocking" the progress of other asynchronous events. This means that when an asynchronous event occurs (like a mouse click, a timer firing, or an XMLHttpRequest completing) it gets queued up to be executed later (how this queueing actually occurs surely varies from browser-to-browser, so consider this to be a simplification).
To start with, within the first block of JavaScript, two timers are initiated: a 10ms setTimeout and a 10ms setInterval. Due to where and when the timer was started it actually fires before we actually complete the first block of code. Note, however, that it does not execute immediately (it is incapable of doing that, because of the threading). Instead that delayed function is queued in order to be executed at the next available moment.

Additionally, within this first JavaScript block we see a mouse click occur. The JavaScript callbacks associated with this asynchronous event (we never know when a user may perform an action, thus it's consider to be asynchronous) are unable to be executed immediately thus, like the initial timer, it is queued to be executed later.

After the initial block of JavaScript finishes executing the browser immediately asks the question: What is waiting to be executed? In this case both a mouse click handler and a timer callback are waiting. The browser then picks one (the mouse click callback) and executes it immediately. The timer will wait until the next possible time, in order to execute.

Note that while mouse click handler is executing the first interval callback executes. As with the timer its handler is queued for later execution. However, note that when the interval is fired again (when the timer handler is executing) this time that handler execution is dropped. If you were to queue up all interval callbacks when a large block of code is executing the result would be a bunch of intervals executing with no delay between them, upon completion. Instead browsers tend to simply wait until no more interval handlers are queued (for the interval in question) before queuing more.

We can, in fact, see that this is the case when a third interval callback fires while the interval, itself, is executing. This shows us an important fact: Intervals don't care about what is currently executing, they will queue indiscriminately, even if it means that the time between callbacks will be sacrificed.

Finally, after the second interval callback is finished executing, we can see that there's nothing left for the JavaScript engine to execute. This means that the browser now waits for a new asynchronous event to occur. We get this at the 50ms mark when the interval fires again. This time, however, there is nothing blocking its execution, so it fires immediately.

setTimeout(function(){
/* Some long block of code... */
setTimeout(arguments.callee, 10);
}, 10);

setInterval(function(){
/* Some long block of code... */
}, 10);

These two pieces of code may appear to be functionally equivalent, at first glance, but they are not. Notably the setTimeout code will always have at least a 10ms delay after the previous callback execution (it may end up being more, but never less) whereas the setInterval will attempt to execute a callback every 10ms regardless of when the last callback was executed.

regexp.exec, string.match

via javascript: the definitive guide


string.match

  • if g flag was used: returns an array with the matches

  • if g was not used: an array with the match and the parenthesized subexpressions



'123-456-7890'.match(/\d{3}/g); // Returns ['123', '456’, ‘789’]
'123-456-7890'.match(/(\d{3})-(\d{3})/); // Returns ['123-456', '123', '456']

regexp.exec
Note that exec( ) always includes full details of every match in the array it returns, whether or not regexp is a global pattern. This is where exec( ) differs from String.match( ), which returns much less information when used with global patterns. Calling the exec( ) method repeatedly in a loop is the only way to obtain complete pattern-matching information for a global pattern.

6/03/2010

javascritp regular expression


var re = /\d?/; // 0 or 1
re = /\d+/; // 1 or more
re = /\d*/; // 0 or more
re = /\d{3}/; // Exactly 3 times
re = /\d{3,}/; // 3 or more times
re = /\d{3,5}/; // At least 3, but not more than 5 times



‘aaa’.match(/a+/) // [‘aaa’]
‘aaa’.match(/a+?/) // [‘a’]

11.1.3.1. Nongreedy repetition
The repetition characters listed in Table 11-3 match as many times as possible while still allowing any following parts of the regular expression to match. We say that this repetition is "greedy." It is also possible (in JavaScript 1.5 and later; this is one of the Perl 5 features not implemented in JavaScript 1.2) to specify that repetition should be done in a nongreedy way. Simply follow the repetition character or characters with a question mark: ??, +?, *?, or even {1,5}?. For example, the regular expression /a+/ matches one or more occurrences of the letter a. When applied to the string "aaa", it matches all three letters. But /a+?/ matches one or more occurrences of the letter a, matching as few characters as necessary. When applied to the same string, this pattern matches only the first letter a.

Using nongreedy repetition may not always produce the results you expect. Consider the pattern /a*b/, which matches zero or more letter a's, followed by the letter b. When applied to the string "aaab", it matches the entire string. Now let's use the nongreedy version: /a*?b/. This should match the letter b preceded by the fewest number of a's possible. When applied to the same string "aaab", you might expect it to match only the last letter b. In fact, however, this pattern matches the entire string as well, just like the greedy version of the pattern. This is because regular-expression pattern matching is done by finding the first position in the string at which a match is possible. The nongreedy version of our pattern does match at the first character of the string, so this match is returned; matches at subsequent characters are never even considered.

6/02/2010

The onerror event of the window object

The onerror event of the window object

Defining the onerror event with a function that returns a value of true at the very top of your page suppresses all scripting errors on the page .

window.onerror=function(){
alert('An error has occurred!')
return true
}



window.onerror=function(msg, url, linenumber){
alert('Error message: '+msg+'\nURL: '+url+'\nLine Number: '+linenumber)
return true
}



var errordialog=function(msg, url, linenumber){
var dialog=document.createElement("div")
dialog.className='errordialog'
dialog.innerHTML=' JavaScript Error: ' + msg +' at line number ' + linenumber +'. Please inform webmaster.'
document.body.appendChild(dialog)
return true
}

window.onerror=function(msg, url, linenumber){
return errordialog(msg, url, linenumber)
}

MSDev - AJAX and Client-Side - Javascript: Pass by reference or value?

MSDev - AJAX and Client-Side - Javascript: Pass by reference or value?


function reftest2(a) { a.x = 10; }
c = {x:1, y:2};
reftest2(c);
alert(c.x); // 10

The confusion here results in what exactly the value of a variable is. When an object is passed into a function, its internal address is what gets passed in. That's the "value" of the object. Thus when the function modifies the x member of the object it received, it ends up modifying the same x member as that in the original object. While this might seem like pass-by-reference, it's still pass-by-value.

(If you're a C programmer, this should be totally familiar to you. C uses only pass-by-value as well, and you run into similar behavior when you pass an array into a function.)

All types are passed by value
For reference types (objects, arrays, functions, etc.), the value passed is a pointer
This can have unexpected consequences if you aren't prepared for it; modifying an array passed as an argument will modify the array value outside of the function
This is not the same as passing by reference; you can not perform in place sorting on an array using memory locations, for instance


javascript: the definitive guide
The basic rule in JavaScript is this: primitive types are manipulated by value, and reference types, as the name suggests, are manipulated by reference. Numbers and booleans are primitive types in JavaScriptprimitive because they consist of nothing more than a small, fixed number of bytes that are easily manipulated at the low levels of the JavaScript interpreter. Objects, on the other hand, are reference types. Arrays and functions, which are specialized types of objects, are therefore also reference types. These datatypes can contain arbitrary numbers of properties or elements, so they cannot be manipulated as easily as fixed-size primitive values can. Since object and array values can become quite large, it doesn't make sense to manipulate these types by value, because this could involve the inefficient copying and comparing of large amounts of memory.

Example 3-1. Copying, passing, and comparing by value

// First we illustrate copying by value
var n = 1; // Variable n holds the value 1
var m = n; // Copy by value: variable m holds a distinct value 1

// Here's a function we'll use to illustrate passing by value
// As we'll see, the function doesn't work the way we'd like it to
function add_to_total(total, x)
{
total = total + x; // This line changes only the internal copy of total
}

// Now call the function, passing the numbers contained in n and m by value.
// The value of n is copied, and that copied value is named total within the
// function. The function adds a copy of m to that copy of n. But adding
// something to a copy of n doesn't affect the original value of n outside
// of the function. So calling this function doesn't accomplish anything.
add_to_total(n, m);

// Now, we'll look at comparison by value.
// In the following line of code, the literal 1 is clearly a distinct numeric
// value encoded in the program. We compare it to the value held in variable
// n. In comparison by value, the bytes of the two numbers are checked to
// see if they are the same.
if (n == 1) m = 2; // n contains the same value as the literal 1; m is now 2


Example 3-2. Copying, passing, and comparing by reference

// Here we create an object representing the date of Christmas, 2007
// The variable xmas contains a reference to the object, not the object itself
var xmas = new Date(2007, 11, 25);
// When we copy by reference, we get a new reference to the original object
var solstice = xmas; // Both variables now refer to the same object value

// Here we change the object through our new reference to it
solstice.setDate(21);

// The change is visible through the original reference, as well
xmas.getDate( ); // Returns 21, not the original value of 25

// The same is true when objects and arrays are passed to functions.
// The following function adds a value to each element of an array.
// A reference to the array is passed to the function, not a copy of the array.
// Therefore, the function can change the contents of the array through
// the reference, and those changes will be visible when the function returns.
function add_to_totals(totals, x)
{
totals[0] = totals[0] + x;
totals[1] = totals[1] + x;
totals[2] = totals[2] + x;
}

// Finally, we'll examine comparison by reference.
// When we compare the two variables defined above, we find they are
// equal, because they refer to the same object, even though we were trying
// to make them refer to different dates:
(xmas == solstice) // Evaluates to true

// The two variables defined next refer to two distinct objects, both
// of which represent exactly the same date.
var xmas = new Date(2007, 11, 25);
var solstice_plus_4 = new Date(2007, 11, 25);

// But, by the rules of "compare by reference," distinct objects are not equal!
(xmas != solstice_plus_4) // Evaluates to true


Before we leave the topic of manipulating objects and arrays by reference, let's clear up a point of nomenclature. The phrase "pass by reference" can have several meanings. To some readers, the phrase refers to a function-invocation technique that allows a function to assign new values to its arguments and to have those modified values visible outside the function. This is not the way the term is used in this book. Here, I mean simply that a reference to an object or arraynot the object itselfis passed to a function. A function can use the reference to modify properties of the object or elements of the array. But if the function overwrites the reference with a reference to a new object or array, that modification is not visible outside the function. Readers familiar with the other meaning of this term may prefer to say that objects and arrays are passed by value, but the value that is passed is actually a reference rather than the object itself. Example 3-3 illustrates this issue.

Example 3-3. References themselves are passed by value

// This is another version of the add_to_totals( ) function. It doesn't
// work, though, because instead of changing the array itself, it tries to
// change the reference to the array.
function add_to_totals2(totals, x)
{
newtotals = new Array(3);
newtotals[0] = totals[0] + x;
newtotals[1] = totals[1] + x;
newtotals[2] = totals[2] + x;
totals = newtotals; // This line has no effect outside of the function
}

Billy Hoffman - JSConf 2010

Billy Hoffman - JSConf 2010

Dehydrating Code
* Converts any string into whitespace
* 7 bit per character: 1 = space, 0 = tab
* \n means we are done
* 'a' = 1100001
* dehydrate('a') = space, space, tab, tab, tab, ...


function dehydrate(s) {
var r = new Array();
for(var i=0; i if (s.charCodeAt(i) & (Math.pow(2, j))) {
r.push(' ');
} else {
r.push('\t');
}
}
r.push('\n');
return r.join('');
}

function hydrate (s) {
var r = []; var curr = 0;
while(s.charAt(curr) != '\n') {
var tmp = 0;
for (var i=6; i>=0; i--) {
if (s.charAt(curr) == '') tmp = tmp | (Math.pow(2, i));
curr++;
}
r.push(String.fromCharCode(tmp));
}
return r.join('');
}


//startevil

//endevil

var html = document.body.innerHTML;
var start = html.indexOf("//start" + "tevil");
var end = html.indexOf("//end" + "evil");
eval(dydrate(html.substring(start+12, end)));

some trucs and machins about google go

http://www.scribd.com/vacuum?url=http://dept-info.labri.fr/~narbel/Lect/go-lecture.pdf

6/01/2010

javascript prototype

__proto__ is not the same as prototype. __proto__ is a property of the instances(object), whereas prototype is a property of the constructor functions(function).


var o = {};
console.log(o.__proto__); // Object { }
console.log(o.prototype); // undefined
console.log(o.__proto__ == Object.prototype); // true, means pointing to the same object
console.log(o.constructor.prototype == o.__proto); // true



function Gadget(name, color) {
this.name = name;
this.color = color;
this.whatAreYou = function(){
return 'I am a ' + this.color + ' ' + this.name;
}
}

Gadget.prototype.price = 100;
Gadget.prototype.rating = 3;
Gadget.prototype.getInfo = function() {
return 'Rating: ' + this.rating + ', price: ' + this.price;
};

var newtoy = new Gadget('webcam', 'black');

console.log(newtoy) // Object {name="webcam", more...}
console.log(newtoy.constructor); // Gadget(name, color)
console.log(newtoy.constructor.prototype); // Object {price=100, more...}
console.log(newtoy.constructor.prototype.constructor); // Gadget (name, color)


Every object also gets the isPrototypeOf() method. This method tells you whether that specific object is used as a prototype of another object.

var monkey = {
feeds: 'benana',
breathes: 'air'
};

function Human() {};
Human.prototype = monkey;

var developer = new Human();
developer.feeds = 'pizza';
developer.hacks = 'JavaScript';

console.log(developer.__proto__); // Object { feeds="benana", more...}
console.log(typeof developer.__proto__); // object
console.log(typeof developer.prototype); // undefined
console.log(monkey.isPrototypeOf(developer)); // true, relationship between obejects
console.log(monkey.isPrototypeOf(Human)); // false


Prototype Chaining
As you already know, every function has a prototype property, which contains an object. When this function is invoked using the new operator, an object is created and this object has a secret link to the prototype object. The secret link (called __proto__ in some environments) allows methods and properties of the prototype object to be used as if they belong to the newly-created object.

function Shape(){
this.name = 'shape';
this.toString = function() {return this.name;};
}

function TwoDShape(){
this.name = '2D shape';
}

function Triangle(side, height) {
this.name = 'Triangle';
this.side = side;
this.height = height;
this.getArea = function(){return this.side * this.height / 2;};
}
TwoDShape.prototype = new Shape();
Triangle.prototype = new TwoDShape();

5/31/2010

Expression Versus Statement - Stack Overflow

Expression Versus Statement - Stack Overflow

Expression: Something which evaluates to a value. Example: 1+2/x
Statement: A line of code which does something. Example: GOTO 100

In the earliest general-purpose programming languages, like FORTRAN, the distinction was crystal-clear. In FORTRAN, a statement was one unit of execution, a thing that you did. The only reason it wasn't called a "line" was because sometimes it spanned multiple lines. An expression on its own couldn't do anything... you had to assign it to a variable.
1 + 2 / X

is an error in FORTRAN, because it doesn't do anything. You had to do something with that expression:
X = 1 + 2 / X

FORTRAN didn't have a grammar as we know it today—that idea was invented, along with Backus-Naur Form (BNF), as part of the definition of Algol-60. At that point the semantic distinction ("have a value" versus "do something") was enshrined in syntax: one kind of phrase was an expression, and another was a statement, and the parser could tell them apart.

Designers of later languages blurred the distinction: they allowed syntactic expressions to do things, and they allowed syntactic statements that had values. The earliest popular language example that still survives is C. The designers of C realized that no harm was done if you were allowed to evaluate an expression and throw away the result. In C, every syntactic expression can be a made into a statement just by tacking a semicolon along the end:
1 + 2 / x;

is a totally legit statement even though absolutely nothing will happen. Similarly, in C, an expression can have side-effects—it can change something.
1 + 2 / callfunc(12);

because callfunc might just do something useful.

Once you allow any expression to be a statement, you might as well allow the assignment operator (=) inside expressions. That's why C lets you do things like
callfunc(x = 2);

This evaluates the expression x = 2 (assigning the value of 2 to x) and then passes that (the 2) to the function callfunc.

This blurring of expressions and statements occurs in all the C-derivatives (C, C++, C#, and Java), which still have some statements (like while) but which allow almost any expression to be used as a statement (in C# only assignment, call, increment, and decrement expressions may be used as statements; see Scott Wisniewski's answer).

Having two "syntactic categories" (which is the technical name for the sort of thing statements and expressions are) can lead to duplication of effort. For example, C has two forms of conditional, the statement form
if (E) S1; else S2;

and the expression form
E ? E1 : E2

And sometimes people want duplication that isn't there: in standard C, for example, only a statement can declare a new local variable—but this ability is useful enough that the GNU C compiler provides a GNU extension that enables an expression to declare a local variable as well.

Designers of other languages didn't like this kind of duplication, and they saw early on that if expressions can have side effects as well as values, then the syntactic distinction between statements and expressions is not all that useful—so they got rid of it. Haskell, Icon, Lisp, and ML are all languages that don't have syntactic statements—they only have expressions. Even the class structured looping and conditional forms are considered expressions, and they have values—but not very interesting ones.

Lazy Function Definition Pattern

Lazy Function Definition Pattern


var foo = function() {
var t = new Date();
foo = function() {
return t;
};
return foo();
};

When foo is called the first time, we instantiate a new Date object and reassign foo to a new function which has that Date object in it's closure. Then before the end of the first call to foo the new function value of foo is called and supplies the return value.

Subsequent calls to foo simply return the value of t that is stored in it's closure. This is a fast lookup and efficient especially if the conditionals used in the previous solutions are many and complex.

Another way of thinking about this this pattern is that the outer function that is first assigned to foo is a promise. It promises that the first time it is run it will redefine foo to a more useful function. The term "promise" loosely comes from Scheme's lazy evaluation mechanism. Any JavaScript programmer really ought to study Scheme as there is more written about functional programming for Scheme then exists for JavaScript.

Enhanced Javascript Lazy Function Definition Pattern
The lazy function definition pattern is pretty simple at heart: you have a function which does some work, caches the results through a closure variable, and then overwrites itself with a new function that simply returns the closure variable. So the first time you run a function will be the only time the function does any work. Each subsequent call is “lazy” and just returns the results of that first call.