<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Leon&#039;s blog &#187; 软件开发</title>
	<atom:link href="http://www.leonzhang.com/category/itweb/%e8%bd%af%e4%bb%b6%e5%bc%80%e5%8f%91/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.leonzhang.com</link>
	<description>关注: 开源&#38;互联网, GTD with open source and Web</description>
	<lastBuildDate>Mon, 30 Jan 2012 14:24:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Sublime Text 2 更新了, beta Build 2165</title>
		<link>http://www.leonzhang.com/2012/01/13/sublime-text-2-beta-build-2165/</link>
		<comments>http://www.leonzhang.com/2012/01/13/sublime-text-2-beta-build-2165/#comments</comments>
		<pubDate>Fri, 13 Jan 2012 03:08:58 +0000</pubDate>
		<dc:creator>leon</dc:creator>
				<category><![CDATA[软件开发]]></category>
		<category><![CDATA[sublime]]></category>

		<guid isPermaLink="false">http://www.leonzhang.com/?p=916</guid>
		<description><![CDATA[昨天Sublime Text 2 释出了新的beta版本，2165。除了修正了很多bugs，另外有几个新特性很值得关注了。 首当其冲的是速度方面有了很大的提升，现在启动速度明显快了。看来是想尽快摘掉Beta这顶帽子啊。 重新设计了默认的界面主题， 现在这个主题非常类似soda theme的风格，已经完全不必再安装soda theme扩展了. Auto complete自动补齐功能。自动补齐会使用字典和snippets作为补齐的列表源，速度非常快，不会对你的输入有明显的干扰。对我这样英语不好的同志很有帮助啊，呵呵。这里还有一个小改进，是把Tab键用作自动补齐，而保留Enter键继续作为Enter，而不进行补齐；开启这个功能的选项是auto_complete_commit_on_tab。 通过Ctrl+Shift+T来打开最近关闭的文件，这个行为跟多标签浏览器里打开最近关闭的标签设计一样。又一个扩展Open Recent Files牺牲了。 我升级后，没有发现与现有扩展的明显冲突。喜欢尝鲜的朋友赶快去升级啊。]]></description>
			<content:encoded><![CDATA[<p>昨天<a href="http://www.sublimetext.com/2">Sublime Text 2</a> 释出了新的beta版本，<a href="http://www.sublimetext.com/blog/articles/sublime-text-2-build-2165">2165</a>。除了修正了很多<a href="http://www.sublimetext.com/2">bugs</a>，另外有几个新特性很值得关注了。</p>
<ol>
<li>首当其冲的是速度方面有了很大的提升，现在启动速度明显快了。看来是想尽快摘掉Beta这顶帽子啊。 </li>
<li>重新设计了默认的界面主题， 现在这个主题非常类似<a href="https://github.com/buymeasoda/soda-theme">soda theme</a>的风格，已经完全不必再安装<a href="https://github.com/buymeasoda/soda-theme">soda theme</a>扩展了.<br />
<img src="http://c758482.r82.cf2.rackcdn.com/new_theme_small.png" alt="new theme" /></li>
<li>Auto complete自动补齐功能。自动补齐会使用字典和snippets作为补齐的列表源，速度非常快，不会对你的输入有明显的干扰。对我这样英语不好的同志很有帮助啊，呵呵。这里还有一个小改进，是把Tab键用作自动补齐，而保留Enter键继续作为<strong><em>Enter</em></strong>，而不进行补齐；开启这个功能的选项是<strong><em>auto_complete_commit_on_tab</em></strong>。<br />
<img src="http://c758482.r82.cf2.rackcdn.com/auto_complete_small.png" alt="Auto complete" /></li>
<li>通过<strong><em>Ctrl+Shift+T</em></strong>来打开最近关闭的文件，这个行为跟多标签浏览器里打开最近关闭的标签设计一样。又一个扩展<a href="https://github.com/spadgos/sublime-OpenRecentFiles">Open Recent Files</a>牺牲了。</li>
</ol>
<p>我升级后，没有发现与现有扩展的明显冲突。喜欢尝鲜的朋友赶快去升级啊。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.leonzhang.com/2012/01/13/sublime-text-2-beta-build-2165/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>在sublime text 2里使用ctags扩展</title>
		<link>http://www.leonzhang.com/2012/01/11/using-ctags-in-sublime-text-2/</link>
		<comments>http://www.leonzhang.com/2012/01/11/using-ctags-in-sublime-text-2/#comments</comments>
		<pubDate>Wed, 11 Jan 2012 15:07:01 +0000</pubDate>
		<dc:creator>leon</dc:creator>
				<category><![CDATA[软件开发]]></category>
		<category><![CDATA[ctags]]></category>
		<category><![CDATA[sublime]]></category>

		<guid isPermaLink="false">http://www.leonzhang.com/?p=899</guid>
		<description><![CDATA[在上一篇关于Sublime Text 2的文章我提到了可以使用CTags扩展。 使用Sublime Package Control安装CTags扩展很容易。按快捷键”Ctrl+Shift+P”，然后选择安装package，再选择CTags就可以了。 在Linux和Mac上，CTags扩展可以自动生成tags文件，你只需要按下快捷方式”Ctrl+t,Ctrl+b”即可。 其实他就是在当前目录执行了一下”ctags -R -f .tags”命令。 在Windows平台上，我不知道有没有ctags命令，如果没有CTags扩展是没办法起作用的。不过只要能用其他工具生成tags文件，注意tags文件要放在项目的当前目录，并且文件名要是”.tags”. CTags基本上与Vim下的CTaga一致，当光标停在某个函数上时，按下快捷键”Ctrl＋Alt＋]”，就可以打开函数所在的文件，并跳转到相应位置。 如果要返回之前的位置只需要按下”Ctrl＋Alt＋[“即可。 由于使用Sublime Package Control安装扩展太方便了，我经常会安装很多。这其实是个不好的习惯，大部分扩展安装以后可能很少用到。 而且可能是Sublime Text 2还比较新的缘故吧，有些扩展之间还会冲突。 比如EncodingHelper跟CTags扩展就有冲突。EncodingHelper会造成CTags只能打开函数所在的文件, 却跳转不到精确的位置。 另外Mac上缺省的CTags似乎并不是那个Exuberant CTags，不知道是什么版本，参数都不一样！所以在Mac上还要先更改CTags，安装步骤如下。]]></description>
			<content:encoded><![CDATA[<p>在<a href="http://www.leonzhang.com/2011/12/19/sublime-text-2a-editor-for-everybody/">上一篇关于Sublime Text 2的文章</a>我提到了可以使用<a href="https://github.com/SublimeText/CTags">CTags扩展</a>。</p>
<p>使用<a href="http://wbond.net/sublime_packages/package_control">Sublime Package Control</a>安装<a href="https://github.com/SublimeText/CTags">CTags扩展</a>很容易。按快捷键”Ctrl+Shift+P”，然后选择安装package，再选择CTags就可以了。</p>
<p>在Linux和Mac上，CTags扩展可以自动生成tags文件，你只需要按下快捷方式”Ctrl+t,Ctrl+b”即可。<br />
其实他就是在当前目录执行了一下”ctags -R -f .tags”命令。<br />
在Windows平台上，我不知道有没有ctags命令，如果没有CTags扩展是没办法起作用的。不过只要能用其他工具生成tags文件，注意tags文件要放在项目的当前目录，并且文件名要是”.tags”.</p>
<p>CTags基本上与Vim下的CTaga一致，当光标停在某个函数上时，按下快捷键”Ctrl＋Alt＋]”，就可以打开函数所在的文件，并跳转到相应位置。<br />
如果要返回之前的位置只需要按下”Ctrl＋Alt＋[“即可。</p>
<p>由于使用<a href="http://wbond.net/sublime_packages/package_control">Sublime Package Control</a>安装扩展太方便了，我经常会安装很多。这其实是个不好的习惯，大部分扩展安装以后可能很少用到。<br />
而且可能是Sublime Text 2还比较新的缘故吧，有些扩展之间还会冲突。<br />
比如<a href="https://github.com/SublimeText/EncodingHelper">EncodingHelper</a>跟<a href="https://github.com/SublimeText/CTags">CTags扩展</a>就有冲突。EncodingHelper会造成CTags只能打开函数所在的文件, 却跳转不到精确的位置。</p>
<p>另外Mac上缺省的CTags似乎并不是那个<a href="http://ctags.sourceforge.net/">Exuberant CTags</a>，不知道是什么版本，参数都不一样！所以在Mac上还要先更改CTags，安装步骤如下。</p>
<pre class="brush: jscript; title: ; notranslate">
curl -O http://prdownloads.sourceforge.net/ctags/ctags-5.8.tar.gz
tar xzvf ctags-5.8.tar.gz
cd ctags-5.8
./configure
make
sudo make install
</pre></p>
]]></content:encoded>
			<wfw:commentRss>http://www.leonzhang.com/2012/01/11/using-ctags-in-sublime-text-2/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>使用Html5 video在iPad/iPhone上碰到的几个问题</title>
		<link>http://www.leonzhang.com/2011/12/31/html5-video-ios-problems/</link>
		<comments>http://www.leonzhang.com/2011/12/31/html5-video-ios-problems/#comments</comments>
		<pubDate>Sat, 31 Dec 2011 06:00:04 +0000</pubDate>
		<dc:creator>leon</dc:creator>
				<category><![CDATA[软件开发]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[ios]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://www.leonzhang.com/?p=868</guid>
		<description><![CDATA[最近使用mediaelementjs做一个iPad上的Html5的video标签的播放器包装. 首先感谢一下mediaelementjs这样的开源项目, 可用度极高, 代码质量明显比我自己写要好多了, 模块化清晰, 许可证很开放(MIT). 开发的过程中遇到了些浏览器兼容问题, 也涉及到一下iPad这样的平板平板设备上的浏览器与桌面浏览器在用户行为设计上的不同的问题. 下面罗列一下: 0. position:fixed 最著名的应该是iOS5之前的版本不支持css的 position:fixed 了吧. 1. 脱离浏览器的视频播放和全屏问题 在手机上, 如iPhone, 浏览器对video标签的处理, 基本上是直接使用系统的媒体播放器播放. 这时由于已经脱离了浏览器, 所以没有办法在播放视频的同时在屏幕上叠加任何显示元素. iPad好一点, 能在页面内直接播放视频, 但是一但用户选择了全屏播放, 则进入iPhone一样的状态. 只有桌面上的Chrome对这个支持的最好, 全屏状态下依然能够叠加浏览器里元素; Firefox逊色些, 全屏并没有全屏显示, 而是把视频充满了当前浏览器窗口. 2. 音量控制问题 在iOS设备上, 浏览器没有办法通过Javascript来操作音量控制, 不管是调节音量大小, 还是静音都不行. 读取当前音量也永远只会得到1. 这又是Apple故意的吧. 3. 剪贴板问题 在iOS设备上, 不能通过Javascript访问系统剪贴板. 用户只能在文字上单击, 调出系统的拷贝粘贴按钮. 要是不想让用户拷贝粘贴倒是有办法, 使用这个CSS. 4. 文本框文字选取问题 在iOS设备上, 不能通过Javascript访问textarea元素的select()来选中该元素的文字, 得到的只不过是把光标移到到了文字的最后位置. 5. 文本框滚动条问题 在iOS设备上, [...]]]></description>
			<content:encoded><![CDATA[<p>最近使用<a href="http://mediaelementjs.com/">mediaelementjs</a>做一个iPad上的Html5的video标签的播放器包装.<br />
首先感谢一下<a href="http://mediaelementjs.com/">mediaelementjs</a>这样的开源项目, 可用度极高, 代码质量明显比我自己写要好多了, 模块化清晰, 许可证很开放(MIT).<br />
<img src="http://blog.mediaelementjs.com/wp-content/uploads/2010/11/medialement-api.png" alt="" /></p>
<p>开发的过程中遇到了些浏览器兼容问题, 也涉及到一下iPad这样的平板平板设备上的浏览器与桌面浏览器在用户行为设计上的不同的问题. 下面罗列一下:</p>
<p><strong>0. position:fixed</strong><br />
    最著名的应该是iOS5之前的版本不支持css的 position:fixed 了吧.</p>
<p><strong>1. 脱离浏览器的视频播放和全屏问题</strong><br />
    在手机上, 如iPhone, 浏览器对video标签的处理, 基本上是直接使用系统的媒体播放器播放. 这时由于已经脱离了浏览器, 所以没有办法在播放视频的同时在屏幕上叠加任何显示元素. iPad好一点, 能在页面内直接播放视频, 但是一但用户选择了全屏播放, 则进入iPhone一样的状态. 只有桌面上的Chrome对这个支持的最好, 全屏状态下依然能够叠加浏览器里元素; Firefox逊色些, 全屏并没有全屏显示, 而是把视频充满了当前浏览器窗口. </p>
<p><strong>2. 音量控制问题</strong><br />
    在iOS设备上, 浏览器没有办法通过Javascript来操作音量控制, 不管是调节音量大小, 还是静音都不行. 读取当前音量也永远只会得到1. 这又是<a href="http://developer.apple.com/library/safari/#documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html#//apple_ref/doc/uid/TP40009523-CH5-SW11">Apple故意</a>的吧.</p>
<p><strong>3. 剪贴板问题</strong><br />
    在iOS设备上, 不能通过Javascript访问系统剪贴板. 用户只能在文字上单击, 调出系统的拷贝粘贴按钮. 要是不想让用户拷贝粘贴倒是有办法, 使用这个CSS.</p>
<pre class="brush: css; title: ; notranslate">
    -webkit-user-select: none;
</pre>
<p><strong>4. 文本框文字选取问题</strong><br />
    在iOS设备上, 不能通过Javascript访问textarea元素的select()来选中该元素的文字, 得到的只不过是把光标移到到了文字的最后位置.</p>
<p><strong>5. 文本框滚动条问题</strong><br />
    在iOS设备上, <a href="http://stackoverflow.com/questions/2869946/mobile-safari-shows-no-scrollbars-on-textarea">textarea元素没有滚动条</a>, 你看不出到了, textarea什么位置了. 滚动只能通过双指滑动来实现, 这应该算是多点触摸设备的特性吧.</p>
<p><strong>6. 边框问题</strong><br />
    默认情况下, iOS在你单击元素时, 会显示一个难看的边框. 像是在使用Firebug做调试一样, 我想最终用户可不行看到这个. 这个可以通过CSS修正. </p>
<pre class="brush: css; title: ; notranslate">
    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
</pre>
<p><strong>7. touch events的支持问题</strong><br />
    jQuery本身不支持touch events, 所以同jQuery绑定如touchmove这样的事件事, 收不到事件. 因为jQuery复制touchmove的event对象是有些属性读不到, 认为这个事件不合法直接跳掉了. 直接使用DOM元素的addEventListener()方法没问题.</p>
<p>参考文档:</p>
<ul>
<li><a href="http://stackoverflow.com/questions/3006647/list-of-known-safari-on-ipad-differences-over-desktop-safari">List of known “Safari on iPad” differences over “Desktop Safari”</a></li>
<li><a href="http://blog.millermedeiros.com/2011/04/unsolved-html5-video-issues-on-ios/">UNSOLVED HTML5 VIDEO ISSUES ON IOS</a></li>
<li><a href="http://developer.apple.com/library/safari/#technotes/tn2010/tn2262/_index.html">Preparing Your Web Content for iPad</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.leonzhang.com/2011/12/31/html5-video-ios-problems/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>javascript里delete操作符什么时候能成功删除变量?</title>
		<link>http://www.leonzhang.com/2011/12/31/javascript-delete-operator/</link>
		<comments>http://www.leonzhang.com/2011/12/31/javascript-delete-operator/#comments</comments>
		<pubDate>Sat, 31 Dec 2011 03:42:16 +0000</pubDate>
		<dc:creator>leon</dc:creator>
				<category><![CDATA[软件开发]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.leonzhang.com/?p=862</guid>
		<description><![CDATA[ECMAScript里关于delete操作符的解释晦涩的很, 实在不是我能理解的. 有兴趣你可以去看看. 实际中使用中, 经常会碰到Javascript变量有时候能成功删除, 有时候却不掉成功删除的情况. 这篇Understanding delete牛文详细解释了, 为什么会这样, 什么样的变量能成功delete, 什么样的不能成功delete. 简而言之, 就是通过”声明“方式创建的变量不能成功删除, 通过”赋值“方式创建的变量能成功删除; 一但一个变量创建后, 它能不能被删除的属性将不会改变. 一个特例是通过eval()函数执行动态代码创建出来的变量,都是可以删除的. 如下面这段代码在Firefox/Chrome/Nodejs里的运行结果如下: Firebug的console里直接定义的变量(不包括在函数里定义的变量), 似乎是因为以eval()的方式在运行代码. 所以通过在Firebug的console里输入代码创建出来的变量,是可以删除的. Chrome等webkit系的浏览器的开发工具没有这个问题. 这一点在调试代码时可能会引起奇怪的现象.]]></description>
			<content:encoded><![CDATA[<p>ECMAScript里关于delete操作符的解释晦涩的很, 实在不是我能理解的. 有兴趣你可以去<a href="http://www.ecmascript.org/docs.php">看看</a>.</p>
<p>实际中使用中, 经常会碰到Javascript变量有时候能成功删除, 有时候却不掉成功删除的情况.<br />
这篇<a href="http://perfectionkills.com/understanding-delete/">Understanding delete牛文</a>详细解释了, 为什么会这样, 什么样的变量能成功delete, 什么样的不能成功delete.</p>
<p>简而言之, 就是通过”<strong>声明</strong>“方式创建的变量不能成功删除, 通过”<strong>赋值</strong>“方式创建的变量能成功删除; 一但一个变量创建后, 它能不能被删除的属性将不会改变. 一个特例是通过eval()函数执行动态代码创建出来的变量,都是可以删除的.<br />
如下面这段代码在Firefox/Chrome/Nodejs里的运行结果如下:</p>
<pre class="brush: jscript; title: ; notranslate">
(function(global){
    var aaa = &quot;aaa&quot;;
    bbb = &quot;bbb&quot;;
    global.ccc = &quot;ccc&quot;;
    eval(&quot;var ddd='ddd';&quot;);
    console.log(delete aaa);
    console.log(delete bbb);
    console.log(delete ccc);
    console.log(delete ddd);
}(this));
</pre>
<p><a href="http://www.flickr.com/photos/hileon/6604553305/" title="scrn2011-12-31 12 04 18 by hileonzhang, on Flickr"><img src="http://farm8.staticflickr.com/7145/6604553305_89aff58ca5.jpg" width="500" height="367" alt="scrn2011-12-31 12 04 18"></a></p>
<p>Firebug的console里直接定义的变量(不包括在函数里定义的变量), 似乎是因为以eval()的方式在运行代码. 所以通过在Firebug的console里输入代码创建出来的变量,是可以删除的. Chrome等webkit系的浏览器的开发工具没有这个问题. 这一点在调试代码时可能会引起奇怪的现象.</p>
<pre class="brush: jscript; title: ; notranslate">
//在console里粘贴运行下面的代码
var aaa = &quot;aaa&quot;;
console.log(delete aaa);
//在Chrome的开发工具里返回是false, 在Firebug的console里返回是true.
</pre>
<p><a href="http://www.flickr.com/photos/hileon/6604553731/" title="scrn2011-12-31 12 13 13 by hileonzhang, on Flickr"><img src="http://farm8.staticflickr.com/7034/6604553731_54598d0d89.jpg" width="335" height="236" alt="scrn2011-12-31 12 13 13"></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.leonzhang.com/2011/12/31/javascript-delete-operator/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>对象赋值时的Javascript prototype chain</title>
		<link>http://www.leonzhang.com/2011/12/22/javascript-property-assign-value-and-prototype-chain/</link>
		<comments>http://www.leonzhang.com/2011/12/22/javascript-property-assign-value-and-prototype-chain/#comments</comments>
		<pubDate>Thu, 22 Dec 2011 13:13:28 +0000</pubDate>
		<dc:creator>leon</dc:creator>
				<category><![CDATA[软件开发]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[prototype]]></category>

		<guid isPermaLink="false">http://www.leonzhang.com/?p=853</guid>
		<description><![CDATA[在Web程序员应该知道的Javascript prototype原理里,说到了prototype chain. 但是有一点要特别注明一下, 那就是prototype chain只在对对象的方法和属性调用和读取时有效, 遵循沿着prototype查找方法和属性的规律; 但是在对对象属性进行赋值时, 并不遵循这一规律. 在对Javascript对象的属性进行赋值时, 原则是这样的: 1. 如果该对象本身有这个属性, 则对该属性赋值 2. 如果该对象本身没有这个属性, 则在该对象上新建一个该属性, 并进行赋值. (这时不会通过__proto__属性, 找该对象的prototype, 检查prototype上有没有该属性, 然后在prototype的属性上赋值.) 举个简单的例子: 看console里打出了的对象应该比较清楚. 用对象的数组写法可能更容易理解些.]]></description>
			<content:encoded><![CDATA[<p>在<a href="http://www.leonzhang.com/2011/12/20/javascript-prototype/">Web程序员应该知道的Javascript prototype原理</a>里,说到了prototype chain. 但是有一点要特别注明一下, 那就是prototype chain只在对对象的方法和属性调用和读取时有效, 遵循沿着prototype查找方法和属性的规律; 但是在对对象属性进行赋值时, 并不遵循这一规律.</p>
<p>在对Javascript对象的属性进行赋值时, 原则是这样的:<br />
1. 如果该对象本身有这个属性, 则对该属性赋值<br />
2. 如果该对象本身没有这个属性, 则在该对象上<strong>新建</strong>一个该属性, 并进行赋值. (这时<strong>不会</strong>通过__proto__属性, 找该对象的prototype, 检查prototype上有没有该属性, 然后在prototype的属性上赋值.)</p>
<p>举个简单的例子:</p>
<pre class="brush: jscript; title: ; notranslate">
var Car = function(){
  this.color = &quot;red&quot;;
}
var Jeep = function(){};
Jeep.prototype = new Car();

var myCar= new Jeep();
console.log(myCar.color);
console.log(myCar);
//这时myCar对象本身上并没有color属性,
//访问myCar.color得到的结果是&quot;red&quot;,
//因为这时prototype chain起作用了.

myCar.color = &quot;green&quot;;
console.log(myCar.color);
console.log(myCar);
//这时myCar对象上新建了一个color属性, 值是&quot;green&quot;.
//但是它并没有覆盖掉myCar的__proto__上的color的属性.
//这时候如果读取myCar.color, 按prototype chain的搜索顺序,
//首先找到的是myCar对象自身上的属性color, 值是&quot;green&quot;.
</pre>
<p>看console里打出了的对象应该比较清楚.<br />
<a href="http://www.flickr.com/photos/hileon/6554145055/" title="assign value with prototype chain by hileonzhang, on Flickr"><img src="http://farm8.staticflickr.com/7150/6554145055_09852c38f1.jpg" width="296" height="337" alt="assign value with prototype chain"></a></p>
<p>用对象的数组写法可能更容易理解些.</p>
<pre class="brush: jscript; title: ; notranslate">
var Car = function() {
  this[&quot;color&quot;] = &quot;red&quot;;
}
var Jeep = function() {};
Jeep.prototype = new Car();

var myCar= new Jeep();
console.log(myCar); 

myCar[&quot;color&quot;] = &quot;green&quot;;
console.log(myCar);
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.leonzhang.com/2011/12/22/javascript-property-assign-value-and-prototype-chain/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Web程序员应该知道的Javascript prototype原理</title>
		<link>http://www.leonzhang.com/2011/12/20/javascript-prototype/</link>
		<comments>http://www.leonzhang.com/2011/12/20/javascript-prototype/#comments</comments>
		<pubDate>Tue, 20 Dec 2011 14:38:48 +0000</pubDate>
		<dc:creator>leon</dc:creator>
				<category><![CDATA[软件开发]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[prototype]]></category>

		<guid isPermaLink="false">http://www.leonzhang.com/?p=848</guid>
		<description><![CDATA[有同事问了我几个和Javascript的类继承的小问题,我在也不太理解的情况下,胡诌了一通. 回来以后有些内疚, 反省一下, 整理整理Javascript的prototype的原理, 自己清楚点, 也希望对别人也有帮助. 首先js里面没有类这回子事情, 虽然class是js的保留字, 但是到现在也没派上任何用场. 在js里面, 几乎所有的东西都是对象, 函数也是对象, 所以函数可以赋值给别的变量. 另外js对象也可以用数组的方式访问, 也就是说访问obj1.something, 也可以写成obj1['something']. 在js里虽然没有类, 但是有一个在类编程里常用的的概念, Constructor构造器, 或者叫构造函数. 语法上Constructor跟普通的js函数没有区别, 但是Constructor前面加上new关键字就可以产生新的对象. 那么”new Constructor()”这样调用时到底做了什么事情呢? 1. js运行环境首先创建一个空对象 2. 把this变量指向这个对象 3. 把__proto__指向这个构造器的prototype属性 4. 通过this把属性和方法加在这个对象上 5. 最后会把this指向的对象return出来(当然你也可以显示的return别的对象,这是情况跟我讨论的有点不一样) 这里有2个概念比较重要, 第一是Constructor的prototype属性, 它是Constructor的一个保持共享属性和方法的对象. 二通过该Constructor生成的对象的__proto__属性, 它指向了那个prototype对象. 对象的Constructor可以通过该对象的constructor属性获得. 我们定义一个简单的Constructor Demo(), 然后通过他生成一个aDemo对象, 在Chrome的console里把aDemo打出来看到的结果是这样的,这是我们能很清楚的看出这种关系. 换一种写法, 其实跟前面没多大区别, 不过这一次f2()不在创建出来的对象上, 而是在对象的__proto__指向的构造器DemoB上. 这样的好处是当使用DemoB创建很多对象时, 比较节省内存. js的prototype搜索链 prototype Chain js的运行环境是这样使用构造器的prototype的. 当我们对第一个对象调用其方法时, [...]]]></description>
			<content:encoded><![CDATA[<p>有同事问了我几个和Javascript的类继承的小问题,我在也不太理解的情况下,胡诌了一通. 回来以后有些内疚, 反省一下, 整理整理Javascript的prototype的原理, 自己清楚点, 也希望对别人也有帮助.</p>
<p>首先<strong>js里面没有类</strong>这回子事情, 虽然class是js的保留字, 但是到现在也没派上任何用场. 在js里面, 几乎所有的东西都是对象, 函数也是对象, 所以函数可以赋值给别的变量. 另外js对象也可以用数组的方式访问, 也就是说访问obj1.something, 也可以写成obj1['something']. </p>
<p>在js里虽然没有类, 但是有一个在类编程里常用的的概念, Constructor构造器, 或者叫构造函数. 语法上Constructor跟普通的js函数没有区别, 但是Constructor前面加上new关键字就可以产生新的对象.</p>
<p><strong>那么”new Constructor()”这样调用时到底做了什么事情呢?</strong><br />
1. js运行环境首先创建一个空对象<br />
2. 把this变量指向这个对象<br />
3. 把__proto__指向这个构造器的prototype属性<br />
4. 通过this把属性和方法加在这个对象上<br />
5. 最后会把this指向的对象return出来(当然你也可以显示的return别的对象,这是情况跟我讨论的有点不一样)</p>
<p>这里有2个概念比较重要, 第一是Constructor的prototype属性, 它是Constructor的一个保持共享属性和方法的对象. 二通过该Constructor生成的对象的__proto__属性, 它指向了那个prototype对象. 对象的Constructor可以通过该对象的constructor属性获得.</p>
<p>我们定义一个简单的Constructor Demo(), 然后通过他生成一个aDemo对象, 在Chrome的console里把aDemo打出来看到的结果是这样的,这是我们能很清楚的看出这种关系.</p>
<pre class="brush: jscript; title: ; notranslate">
function DemoA(){
  this.title = &quot;this is a demo constructor&quot;;
  this.f1 = function(){}
}
var aDemo = new DemoA();
console.log(aDemo);
</pre>
<p><a href="http://www.flickr.com/photos/hileon/6544059473/" title="jsproto1 by hileonzhang, on Flickr"><img src="http://farm8.staticflickr.com/7168/6544059473_9673d4c407.jpg" width="500" height="161" alt="jsproto1"></a></p>
<p>换一种写法, </p>
<pre class="brush: jscript; title: ; notranslate">
function DemoB(){
  this.title = &quot;this is a demo constructor&quot;;
}
DemoB.prototype.f2 = function () {};
var bDemo = new DemoB();
console.log(bDemo);
</pre>
<p><a href="http://www.flickr.com/photos/hileon/6544059061/" title="jsproto2 by hileonzhang, on Flickr"><img src="http://farm8.staticflickr.com/7156/6544059061_4fbf131085.jpg" width="500" height="165" alt="jsproto2"></a><br />
其实跟前面没多大区别, 不过这一次f2()不在创建出来的对象上, 而是在对象的__proto__指向的构造器DemoB上. 这样的好处是当使用DemoB创建很多对象时, 比较节省内存.</p>
<p><strong>js的prototype搜索链 prototype Chain</strong><br />
js的运行环境是这样使用构造器的prototype的. 当我们对第一个对象调用其方法时, js运行环境首先看, 这个对象本身有没有这个方法, 如果有就直接调用. 如果没找到, 就查找这个对象的__proto__属性指向的对象(就是前面说的该对象的构造器的prototype属性), 如果有该方法就调用, 没有继续查找__proto__属性指向对象的__proto__属性指向的对象, 以此类推. 直到最后, 找到js所有的对象都会指向默认指向的Object(算是js的根对象吧). 所以如果我们给Object上增加个方法, 所以的js对象都能使用. </p>
<p>由于js有对对象函数的prototype chain搜索的特性, 我们可以利用这点来模拟类似其他语言里类(class)的效果. 如:</p>
<pre class="brush: jscript; title: ; notranslate">
function DemoA(){
  this.title = &quot;this is a demo constructor&quot;;
  this.f1 = function(){}
}

function DemoB(){
  this.title = &quot;this is b demo constructor&quot;;
  this.f2 = function(){}
}
DemoB.prototype = new DemoA();

var bDemo = new DemoB();
console.log(bDemo);
</pre>
<p><a href="http://www.flickr.com/photos/hileon/6544059723/" title="jsproto3 by hileonzhang, on Flickr"><img src="http://farm8.staticflickr.com/7172/6544059723_0b67a37a34.jpg" width="500" height="288" alt="jsproto3"></a><br />
这时我们通过bDemo对象, 不但能调用bDemo上的DemoB的f2()方法, 也能__proto__同对对prototype的搜索, 在bDemo上直接调用DemoA的f1()方法.</p>
<p>由于这种写法在语法上太啰嗦, 不容易理解, 我可以定义一个这样的函数.</p>
<pre class="brush: jscript; title: ; notranslate">
function inherit(Child, Parent) {
  Child.prototype = new Parent();
}
</pre>
<p>这样我们前面的例子可以写成这样, 效果是一样的:</p>
<pre class="brush: jscript; title: ; notranslate">
function DemoA(){
  this.title = &quot;this is a demo constructor&quot;;
  this.f1 = function(){}
}

function DemoB(){
  this.title = &quot;this is b demo constructor&quot;;
  this.f2 = function(){}
}

inherit(DemoB, DemoA);

var bDemo = new DemoB();
console.log(bDemo);
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.leonzhang.com/2011/12/20/javascript-prototype/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Sublime text 2:程序员的编辑器,大家的编辑器</title>
		<link>http://www.leonzhang.com/2011/12/19/sublime-text-2a-editor-for-everybody/</link>
		<comments>http://www.leonzhang.com/2011/12/19/sublime-text-2a-editor-for-everybody/#comments</comments>
		<pubDate>Mon, 19 Dec 2011 13:48:28 +0000</pubDate>
		<dc:creator>leon</dc:creator>
				<category><![CDATA[软件开发]]></category>
		<category><![CDATA[ctags]]></category>
		<category><![CDATA[e-texteditor]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[sublime]]></category>
		<category><![CDATA[ultraedit]]></category>
		<category><![CDATA[vim]]></category>
		<category><![CDATA[zen-coding]]></category>

		<guid isPermaLink="false">http://www.leonzhang.com/?p=841</guid>
		<description><![CDATA[我使用过的编辑器主要有: Ultraedit, VIM, e-Texteditor, Sublime text 2. 基本上是从收费到免费,再到无限期试用. 由于我是个程序员, 编辑器除了用来编辑文本, 主要用来写JavaScript/PHP这样的脚步程序. 直到遇见了Sublime text 2以后, 它基本上满足了所有的要求. 我没用过textmate,不敢说Sublime一定比textmate好, 但是我想至少不会差, 而它不光能在Mac上跑, 也能在Windows和Linux上跑. 下面罗列一下Sublime跟我用过的其他编辑器的简单对比. e-Texteditor Apple上的textmate流行以后,轻型开发工具成了web开发人员的潮流. Windows上也出现了一些类似的工具,e-Texteditor就之一.我使用了e一段时间以后,还是回到了Eclipse/PhpStorm. 直到用上Sublime才感觉不想打开那笨重的IDE环境了. Sublime无疑也属于轻型开发工具这一类, 而且到Sublime text 2(还没发布,现在是beta 2139)以后, 甚至有超越textmate的意思, 最近textmate 2的开发步伐也明显加快了,看来是有一定的压力. 速度方面, e使用一段时间以后,开启和编辑速度都会明显下降. Sublime好很多, 至今没有发现性能上的明显变化. 扩展, e的扩展基本上是一些兼容textmate的Snippets. Sublime的扩展明显开放得多, 使用Pyhton编写, 能做的功能也多很多. 试用期, e有30天的试用版,但是到期之后,只需要到注册表里删除e相关键值就可以再用30天. Sublime大度些,可以无限期使用下去,但是不确定Sublime Text 2正式版发布以后是不是还是这样的. 操作系统, e支持Windows,Sublime则在Windows/Linux/Mac上都能使用. VIM VIM绝对是个神器, 几乎无所不能, 可惜学习门槛比较高. 另一个比较差的地方是, 没有一个好的文件管理扩展, 特别是缺乏一个美观的GUI外壳. [...]]]></description>
			<content:encoded><![CDATA[<p>我使用过的编辑器主要有: <a href="http://www.ultraedit.com/">Ultraedit</a>, <a href="http://www.vim.org">VIM</a>, <a href="http://www.e-texteditor.com/">e-Texteditor</a>, <a href="http://www.sublimetext.com/2">Sublime text 2</a>. 基本上是从收费到免费,再到无限期试用. 由于我是个程序员, 编辑器除了用来编辑文本, 主要用来写JavaScript/PHP这样的脚步程序. 直到遇见了Sublime text 2以后, 它基本上满足了所有的要求. 我没用过textmate,不敢说Sublime一定比textmate好, 但是我想至少不会差, 而它不光能在Mac上跑, 也能在Windows和Linux上跑.<br />
<img src="http://www.sublimetext.com/screenshots/pythonHeroSmall.png" alt="" /></p>
<p>下面罗列一下Sublime跟我用过的其他编辑器的简单对比.<br />
<span id="more-841"></span></p>
<h3>e-Texteditor</h3>
<p>Apple上的textmate流行以后,轻型开发工具成了web开发人员的潮流. Windows上也出现了一些类似的工具,e-Texteditor就之一.我使用了e一段时间以后,还是回到了Eclipse/PhpStorm. 直到用上Sublime才感觉不想打开那笨重的IDE环境了. Sublime无疑也属于轻型开发工具这一类, 而且到Sublime text 2(还没发布,现在是beta 2139)以后, 甚至有超越textmate的意思, 最近<a href="http://blog.macromates.com/2011/textmate-2-0-alpha/">textmate 2的开发步伐</a>也明显加快了,看来是有一定的压力.</p>
<p><strong>速度方面</strong>, e使用一段时间以后,开启和编辑速度都会明显下降. Sublime好很多, 至今没有发现性能上的明显变化.<br />
<strong>扩展</strong>, e的扩展基本上是一些兼容textmate的Snippets. Sublime的扩展明显开放得多, 使用Pyhton编写, 能做的功能也多很多.<br />
<strong>试用期</strong>, e有30天的试用版,但是到期之后,只需要到注册表里删除e相关键值就可以再用30天. Sublime大度些,可以无限期使用下去,但是不确定Sublime Text 2正式版发布以后是不是还是这样的.<br />
<strong>操作系统</strong>, e支持Windows,Sublime则在Windows/Linux/Mac上都能使用.</p>
<h3>VIM</h3>
<p>VIM绝对是个神器, 几乎无所不能, 可惜学习门槛比较高. 另一个比较差的地方是, 没有一个好的文件管理扩展, 特别是缺乏一个美观的GUI外壳. 别跟我提GVIM,我感觉那就是一坨xxx.<br />
好在Sublime也有个<strong>VIM扩展</strong>, 基本的VIM功能也支持, 这无疑对VIM用户很有吸引力.<br />
Sublime的查找替换很强大,不但能在当前文件查找,做增量查找,支持正则表达式,在指定的文件夹内的所有文件里查找; 而且最重要的是<strong>速度非常快</strong>.<br />
Sublime还有一cTags扩展, 这样就可以与<a href="http://ctags.sourceforge.net/ctags.html">cTags</a>生产的文件一起使用, 在代码里快速跳转了.<br />
<strong>扩展方便</strong>, Sublime使用python作为扩展的开发语言,并自带一个python的console. 开发调试在一起优势也很明显. 现在已经有很多很不错的扩展,如zen coding, <a href="https://github.com/jashkenas/coffee-script-tmbundle">coffeescript</a>. Sublime通过<strong>Package control</strong>来安装和卸载扩展,明显比vim管理扩展方面方便很多.<br />
Sublime的缺点是收费软件, 如果能开源或者免费, 说不定能创造一个类似VIM一样规模的社区.</p>
<h3>Ultraedit</h3>
<p>Ultraedit是我以前使用了很久的一个编辑器,速度那是没说的.特别是<strong>列模式</strong>,更是在人前炫耀的资本. Ultraedit还有一个<strong>16进制编辑</strong>的功能, 这些编辑器里似乎没有比它做的好. 可惜他只是一个notepad的替代品, 对程序员来时没有特别的吸引力.<br />
Sublime同样支持列编辑(Shift+右键拖拽), 而起还支持一种多位置同时编辑的功能, 使用Ctrl+左键单击选择多个位置,然后就可以在这个多个位置同时输入文字了.</p>
<p>如果你和我一样是个程序员,去尝试一下<a href="http://www.sublimetext.com/2">Sublime text 2</a>吧,我想你也会和我一样喜欢上它的.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.leonzhang.com/2011/12/19/sublime-text-2a-editor-for-everybody/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>如何掌握一个开发语言</title>
		<link>http://www.leonzhang.com/2011/12/13/%e5%a6%82%e4%bd%95%e6%8e%8c%e6%8f%a1%e4%b8%80%e4%b8%aa%e5%bc%80%e5%8f%91%e8%af%ad%e8%a8%80/</link>
		<comments>http://www.leonzhang.com/2011/12/13/%e5%a6%82%e4%bd%95%e6%8e%8c%e6%8f%a1%e4%b8%80%e4%b8%aa%e5%bc%80%e5%8f%91%e8%af%ad%e8%a8%80/#comments</comments>
		<pubDate>Tue, 13 Dec 2011 12:42:24 +0000</pubDate>
		<dc:creator>leon</dc:creator>
				<category><![CDATA[软件开发]]></category>
		<category><![CDATA[学习方法]]></category>

		<guid isPermaLink="false">http://www.leonzhang.com/?p=833</guid>
		<description><![CDATA[* 仔细研读官方文档和一本参考书 * 加入 IRC http://freenode.net/ 上的这个相关channel * 关注 stackoverflow.com 上的相关标签 * 在Github上维护自己的实验项目 * 参加各类会议,与有共同爱好的人交流,Tweet,Blog * 破釜沉舟, 不要给自己留后路, 找借口]]></description>
			<content:encoded><![CDATA[<p>*   仔细研读官方文档和一本参考书<br />
*   加入 IRC http://freenode.net/ 上的这个相关channel<br />
*   关注 stackoverflow.com 上的相关标签<br />
*   在Github上维护自己的实验项目<br />
*   参加各类会议,与有共同爱好的人交流,Tweet,Blog<br />
*   破釜沉舟, 不要给自己留后路, 找借口</p>
]]></content:encoded>
			<wfw:commentRss>http://www.leonzhang.com/2011/12/13/%e5%a6%82%e4%bd%95%e6%8e%8c%e6%8f%a1%e4%b8%80%e4%b8%aa%e5%bc%80%e5%8f%91%e8%af%ad%e8%a8%80/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP扩展 memcache vs. memcached</title>
		<link>http://www.leonzhang.com/2011/06/24/memcached-vs-php-memcache/</link>
		<comments>http://www.leonzhang.com/2011/06/24/memcached-vs-php-memcache/#comments</comments>
		<pubDate>Fri, 24 Jun 2011 15:09:08 +0000</pubDate>
		<dc:creator>leon</dc:creator>
				<category><![CDATA[软件开发]]></category>
		<category><![CDATA[memcached]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.leonzhang.com/?p=773</guid>
		<description><![CDATA[两个扩展的介绍基本一样(memcache, memcached),没有任何特别关于他们之间区别的说明. 那我们什么时候应该用哪个扩展呢? Stackoverflow上有比较详细的讨论: using memcache vs memcached with php 和memcache vs memcached 这里还有一个很清晰表格,对比了这两个扩展的具体特性. 主要区别是php memcached扩展比较新,几乎支持memcached的所有特性(如Delayed Get, Append/Prepend等). 但是它依赖libmemcached才能运行(在debian里面包名是libMemcached5). 所以如果你不使用如Delayed Get这样的特性,又不想多依赖libmemcached库, 完全可以使用memcache扩展. 反之请选择memcached扩展. 不过debian和ubuntu上直接用apt-get install php5-memcached安装的php memcached扩展,libmemcached库有些问题. 很多人报告不能正常使用. memcache扩展由于不依赖libmemcached库,没这个问题. 我的debian 6上也有这个毛病. 必须手工编译libmemcached才行, 命令如下. 然后在/etc/php5/apache2/conf.d/memcached.ini里开启php memcached扩展. 重启apache, 应该就ok了. 你可以用这段php片段测试一下]]></description>
			<content:encoded><![CDATA[<p>两个扩展的介绍基本一样(<a href="http://cn.php.net/manual/en/intro.memcache.php">memcache</a>, <a href="http://www.php.net/manual/en/intro.memcached.php">memcached</a>),没有任何特别关于他们之间区别的说明. 那我们什么时候应该用哪个扩展呢?</p>
<p>Stackoverflow上有比较详细的讨论: <a href="http://stackoverflow.com/questions/1442411/using-memcache-vs-memcached-with-php">using memcache vs memcached with php</a> 和<a href="http://stackoverflow.com/questions/1825256/memcache-vs-memcached">memcache vs memcached</a></p>
<p>这里还有一个很清晰表格,<a href="http://code.google.com/p/memcached/wiki/PHPClientComparison">对比</a>了这两个扩展的具体特性.<br />
主要区别是php memcached扩展比较新,几乎支持memcached的所有特性(如Delayed Get, Append/Prepend等). 但是它依赖<a href="http://tangent.org/552/libmemcached.html">libmemcached</a>才能运行(在debian里面包名是libMemcached5).<br />
所以如果你不使用如Delayed Get这样的特性,又不想多依赖<a href="http://tangent.org/552/libmemcached.html">libmemcached</a>库, 完全可以使用memcache扩展. 反之请选择memcached扩展.</p>
<p>不过debian和ubuntu上直接用apt-get install php5-memcached安装的php memcached扩展,<a href="http://tangent.org/552/libmemcached.html">libmemcached</a>库有些问题. 很多人报告不能正常使用. memcache扩展由于不依赖<a href="http://tangent.org/552/libmemcached.html">libmemcached</a>库,没这个问题.<br />
我的debian 6上也有这个毛病. 必须手工编译libmemcached才行, 命令如下.</p>
<pre class="brush: bash; title: ; notranslate">
apt-get remove php5-memcached

wget http://launchpad.net/libmemcached/1.0/0.50/+download/libmemcached-0.50.tar.gz
tar -zxvf libmemcached-0.50.tar.gz
cd libmemcached-0.50
./configure
make
make test
make install
cd ..

wget http://pecl.php.net/get/memcached-1.0.2.tgz
tar -xzvf memcached-1.0.2.tgz
cd memcached-1.0.2
phpize
./configure
make
make install
</pre>
<p>然后在/etc/php5/apache2/conf.d/memcached.ini里开启php memcached扩展.<br />
重启apache, 应该就ok了.</p>
<p>你可以用这段php片段测试一下</p>
<pre class="brush: php; title: ; notranslate">
$m = new Memcached();
var_dump($m);
echo $m-&gt;addServer('localhost', 11211);

echo $m-&gt;set('int', 99);
echo $m-&gt;set('string', 'a simple string');
echo $m-&gt;set('array', array(11, 12));
/* expire 'object' key in 5 minutes */
echo $m-&gt;set('object', new stdclass, time() + 300);

var_dump($m-&gt;get('int'));
var_dump($m-&gt;get('string'));
var_dump($m-&gt;get('array'));
var_dump($m-&gt;get('object'));
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.leonzhang.com/2011/06/24/memcached-vs-php-memcache/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Log.io: 浏览器里的tail -f</title>
		<link>http://www.leonzhang.com/2011/06/13/log-io_the_tail_f_in_browser/</link>
		<comments>http://www.leonzhang.com/2011/06/13/log-io_the_tail_f_in_browser/#comments</comments>
		<pubDate>Mon, 13 Jun 2011 06:16:40 +0000</pubDate>
		<dc:creator>leon</dc:creator>
				<category><![CDATA[软件开发]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[node.js]]></category>

		<guid isPermaLink="false">http://www.leonzhang.com/?p=769</guid>
		<description><![CDATA[前段时间提到过基于node.js的一个挺好玩的应用TermKit. 现在又碰到一个基于node.js的有意思的应用Log.io. Log.io的目标是在浏览器里实现实时监控日志文件.这跟很多人喜欢在终端上通过tail -f来实时监控日志文件类似. 不过通过node.js的良好的异步模式, Log.io把这个功能很好的在浏览器里搞定了. Log.io由两部分组成, harvester和server. harvester负责监视具体的日志文件,当文件有变化是通知server. harvester可以有多个运行实例, 在不同的机器上收集日志. server则负责处理与使用浏览器监视日志的用户的交互. server只有一个运行实例. Log.io的安装步骤如下. 好了,现在可以访问http://”log.io server所在地址”:8998 来看看效果了. 左侧列表按照harvester分组列出来所有监视的日志文件. 右侧上边是当前选中实时监视的日志,支持通过正则表达式搜索. 右侧下面可以显示某个日志文件的历史内容. 看不到图的请看这里, flickr上新上传的图片怎么都看不到呢?!]]></description>
			<content:encoded><![CDATA[<p>前段时间提到过基于node.js的一个挺好玩的应用<a href="http://www.leonzhang.com/2011/05/24/termkit/">TermKit</a>. 现在又碰到一个基于node.js的有意思的应用<a href="http://logio.org/">Log.io</a>. <a href="http://logio.org/">Log.io</a>的目标是在浏览器里实现实时监控日志文件.这跟很多人喜欢在终端上通过tail -f来实时监控日志文件类似. 不过通过node.js的良好的异步模式, Log.io把这个功能很好的在浏览器里搞定了.</p>
<p><a href="http://logio.org/">Log.io</a>由两部分组成, harvester和server.<br />
harvester负责监视具体的日志文件,当文件有变化是通知server. harvester可以有多个运行实例, 在不同的机器上收集日志.<br />
server则负责处理与使用浏览器监视日志的用户的交互. server只有一个运行实例.</p>
<p>Log.io的安装步骤如下.</p>
<pre class="brush: bash; title: ; notranslate">
#重新以全局模式安装socket.io connect underscore等模块
su -
npm uninstall  socket.io connect underscore
npm install -g  socket.io connect underscore

#下载log.io,并配置
git clone git://github.com/NarrativeScience/Log.io.git log.io
sudo git clone https://github.com/remy/Socket.io-node-client.git /usr/local/lib/node/socket.io.client/
sudo git submodule update --init --recursive
cd log.io/
cd bin/
./configure

#安装server
./install/server

#安装harvester
./install/harvester

#配置要监视的日志 /etc/log.io/harvester.conf
#我添加了apache和log.io自己的日志文件

#开启harvester收集日志
/etc/init.d/log.io-harvester start
</pre>
<p>好了,现在可以访问http://”log.io server所在地址”:8998 来看看效果了.</p>
<p><a href="http://www.flickr.com/photos/hileon/5827742944/" title="Log.io: 浏览器里的tail -f by hileonzhang, on Flickr"><img src="http://farm3.static.flickr.com/2040/5827742944_a2baaa7e89_z.jpg" width="640" height="406" alt="Log.io: 浏览器里的tail -f"></a><br />
左侧列表按照harvester分组列出来所有监视的日志文件. 右侧上边是当前选中实时监视的日志,支持通过正则表达式搜索. 右侧下面可以显示某个日志文件的历史内容.</p>
<p>看不到图的请看<a href="http://weibo.com/1672211361/eC3z4zH2asx">这里</a>, flickr上新上传的图片怎么都看不到呢?!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.leonzhang.com/2011/06/13/log-io_the_tail_f_in_browser/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TermKit, 图形化的Linux终端</title>
		<link>http://www.leonzhang.com/2011/05/24/termkit/</link>
		<comments>http://www.leonzhang.com/2011/05/24/termkit/#comments</comments>
		<pubDate>Tue, 24 May 2011 04:57:54 +0000</pubDate>
		<dc:creator>leon</dc:creator>
				<category><![CDATA[软件开发]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[termkit]]></category>

		<guid isPermaLink="false">http://www.leonzhang.com/?p=760</guid>
		<description><![CDATA[node.js这两年异军突起,基于node.js的工具也越来越多. TermKit就是这两天网络上讨论很多的一个工具.从TermKit作者的blog看,这是运行在Mac,以node.js写服务端,以js+webkit来写客户端,实现的一个图像化的Terminal终端工具. 作者只做了Mac上的开发.我搜索了一个,看到已经有人做了Linux+Chrome的移植.下载下来是了一下,运行不出结果,就在github上comment了一下,没想到作者马上就修正了. 下面是我安装的步骤: 先你就可以了到Chrome里去访问TermKit了。 可以根据输入动态补齐： 这是ls输出的目录结果： 文件也会动态补齐： 可以直接通过cat查看图形文件： 现在好像还有点问题,就是现实出来的目录没有图标.不知道是不是那些显示依赖Mac的什么环境的原因. 不过感觉这样的工具,很难做到Linux Terminal那么通用.但是做一般的显示目录,运行一些命令,显示图像结果这样的任务还是很方便的.]]></description>
			<content:encoded><![CDATA[<p><a href="http://nodejs.org">node.js</a>这两年异军突起,基于<a href="http://nodejs.org">node.js</a>的工具也越来越多.</p>
<p><a href="https://github.com/unconed/TermKit">TermKit</a>就是这两天<a href="http://weibo.com/k/termkit&#038;Refer=STopic_box">网络上讨论很多</a>的一个工具.从<a href="http://acko.net/blog/on-termkit">TermKit作者的blog</a>看,这是运行在Mac,以node.js写服务端,以js+webkit来写客户端,实现的一个图像化的Terminal终端工具.</p>
<p>作者只做了Mac上的开发.我搜索了一个,看到已经有人做了<a href="https://github.com/Floby/TermKit">Linux+Chrome的移植</a>.下载下来是了一下,运行不出结果,就在github上comment了一下,没想到作者马上就修正了.<br />
<span id="more-760"></span><br />
下面是我安装的步骤:</p>
<pre class="brush: bash; title: ; notranslate">
git clone https://github.com/Floby/TermKit.git
cd TermKit/
npm install
node Node/nodekit.js
</pre>
<p>先你就可以了到Chrome里去访问TermKit了。<br />
可以根据输入动态补齐：<br />
<a href="http://www.flickr.com/photos/hileon/5739719325/" title="termkit01 by hileonzhang, on Flickr"><img src="http://farm6.static.flickr.com/5302/5739719325_e33774f96a.jpg" width="500" height="406" alt="termkit01"></a></p>
<p>这是ls输出的目录结果：<br />
<a href="http://www.flickr.com/photos/hileon/5740269976/" title="termkit02 by hileonzhang, on Flickr"><img src="http://farm6.static.flickr.com/5069/5740269976_81d8b7187d.jpg" width="500" height="404" alt="termkit02"></a></p>
<p>文件也会动态补齐：<br />
<a href="http://www.flickr.com/photos/hileon/5754227156/" title="termkit03 by hileonzhang, on Flickr"><img src="http://farm3.static.flickr.com/2641/5754227156_b410db768b.jpg" width="500" height="404" alt="termkit03"></a></p>
<p>可以直接通过cat查看图形文件：<br />
<a href="http://www.flickr.com/photos/hileon/5754227160/" title="termkit04 by hileonzhang, on Flickr"><img src="http://farm3.static.flickr.com/2800/5754227160_2a4d08b465.jpg" width="500" height="404" alt="termkit04"></a></p>
<p>现在好像还有点问题,就是现实出来的目录没有图标.不知道是不是那些显示依赖Mac的什么环境的原因.</p>
<p>不过感觉这样的工具,很难做到Linux Terminal那么通用.但是做一般的显示目录,运行一些命令,显示图像结果这样的任务还是很方便的.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.leonzhang.com/2011/05/24/termkit/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>joomla编辑theme时导致文件权限变成不可写的问题</title>
		<link>http://www.leonzhang.com/2011/03/30/why_joomla_make_file_unwritable/</link>
		<comments>http://www.leonzhang.com/2011/03/30/why_joomla_make_file_unwritable/#comments</comments>
		<pubDate>Tue, 29 Mar 2011 16:03:49 +0000</pubDate>
		<dc:creator>leon</dc:creator>
				<category><![CDATA[软件开发]]></category>
		<category><![CDATA[Joomla]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.leonzhang.com/?p=726</guid>
		<description><![CDATA[最近我编辑joomla的Gantry theme的时候，经常碰到css等文件，保存以后变成不可写“unwritable”的情况。 把这些文件的权限改成755，通过joomla一编辑保存，又变成555了。 在网上Google了一下，发现碰到这个问题的人还真不少。 比如这里和这里,都用一堆人说这事。Gantry theme的用户也说这事。 开始我以为是apache或者php什么地方的配置有问题。但是写了个简单的php脚本，跑了一下发现没这个问题，创建出来的文件的权限很正常。 直到看到这篇文章，才发现这是个老问题，从2006就有人不停的在抱怨了。 起因就是在joomla的模板组件的controller文件administrator/components/com_templates/controller.php里有这么几行代码： 我也没看明白，没什么不使用ftp就要把文件权限改成555？自己改成不可写，然后再告诉用户”那个文件不可写”，还不说问什么。 当然像我这样不求甚解的人很多，这几行代码就被广泛的粘贴复制了。比如本文开头提到的Gantry theme。 更加好笑的是，joomla的team在不断发布新版本。在最近发布的joomla 1.6.1里，似乎处于安全性考虑，之前设置文件权限为755的地方都改成了644。而这几行代码也顺理成章的从555变种成了444。 现在这个问题的解决办法，就是把555换成755，或者444改成644。至于什么时候joomla官方能给出个正解，就不知道了。]]></description>
			<content:encoded><![CDATA[<p>最近我编辑joomla的<a href="http://www.gantry-framework.org/">Gantry theme</a>的时候，经常碰到css等文件，保存以后变成不可写“unwritable”的情况。<br />
把这些文件的权限改成755，通过joomla一编辑保存，又变成555了。</p>
<p>在网上Google了一下，发现碰到这个问题的人还真不少。<br />
比如<a href="http://s2.howna.com/cms/joomla-params-ini-is-unwritable.html">这里</a>和<a href="http://s2.howna.com/cms/joomla-unwritable-css-file.html">这里</a>,都用一堆人说这事。<a href="http://www.gantry-framework.org/">Gantry theme</a>的用户也说<a href="http://forum.joomla.org/viewtopic.php?p=2447198">这事</a>。</p>
<p>开始我以为是apache或者php什么地方的配置有问题。但是写了个简单的php脚本，跑了一下发现没这个问题，创建出来的文件的权限很正常。</p>
<p>直到看到<a href="http://forum.joomla.org/viewtopic.php?t=30796">这篇文章</a>，才发现这是个老问题，从2006就有人不停的在抱怨了。</p>
<p>起因就是在joomla的模板组件的controller文件administrator/components/com_templates/controller.php里有这么几行代码：</p>
<pre class="brush: php; title: ; notranslate">
// Try to make the template file unwriteable
if (!$ftp['enabled'] &amp;&amp; !JPath::setPermissions($file, '0555')) {
	JError::raiseNotice('SOME_ERROR_CODE', JText::_('Could not make the template file unwritable'));
}
</pre>
<p>我也没看明白，没什么不使用ftp就要把文件权限改成555？自己改成不可写，然后再告诉用户”那个文件不可写”，还不说问什么。</p>
<p>当然像我这样不求甚解的人很多，这几行代码就被广泛的粘贴复制了。比如本文开头提到的<a href="http://www.gantry-framework.org/">Gantry theme</a>。</p>
<p>更加好笑的是，joomla的team在不断发布新版本。在最近发布的joomla 1.6.1里，似乎处于安全性考虑，之前设置文件权限为755的地方都改成了644。而这几行代码也顺理成章的从555变种成了444。</p>
<pre class="brush: php; title: ; notranslate">
//administrator/components/com_templates/models/source.php
// Try to make the template file unwriteable.
if (!$ftp['enabled'] &amp;&amp; JPath::isOwner($filePath) &amp;&amp; !JPath::setPermissions($filePath, '0444')) {
	$this-&gt;setError(JText::_('COM_TEMPLATES_ERROR_SOURCE_FILE_NOT_UNWRITABLE'));
	return false;
} else if (!$return) {
	$this-&gt;setError(JText::sprintf('COM_TEMPLATES_ERROR_FAILED_TO_SAVE_FILENAME', $fileName));
	return false;
	}
</pre>
<p>现在这个问题的解决办法，就是把555换成755，或者444改成644。至于什么时候joomla官方能给出个正解，就不知道了。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.leonzhang.com/2011/03/30/why_joomla_make_file_unwritable/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>当mobl遇上新浪微博</title>
		<link>http://www.leonzhang.com/2011/03/25/mobl-weibo-search/</link>
		<comments>http://www.leonzhang.com/2011/03/25/mobl-weibo-search/#comments</comments>
		<pubDate>Thu, 24 Mar 2011 23:38:09 +0000</pubDate>
		<dc:creator>leon</dc:creator>
				<category><![CDATA[软件开发]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[ios]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mobl]]></category>
		<category><![CDATA[PhoneGap]]></category>
		<category><![CDATA[twitter]]></category>
		<category><![CDATA[微博]]></category>
		<category><![CDATA[移动开发]]></category>

		<guid isPermaLink="false">http://www.leonzhang.com/?p=701</guid>
		<description><![CDATA[1.mobl上的twitter trends例子 mobl上关于twitter trends的这个例子，还是蛮好玩的。通过调用twitter的API，得到当下twitter上流行的话题。然后再根据每个话题，显示出最近这个话题的tweets。 2.mobl上的twitter trends例子 照猫画虎，来试试做一个新浪微博的类似应用。查了一下微博的API，遗憾的发现关于话题的API还都处于beta状态。而且要用户登录以后才能调用，不像twitter在不登录的情况下就能调用trends类的API。 新浪微博只有Search类的API有不登录调用的API，我们就拿search模拟一下吧。 3.使用mobl的服务调用json mobl提供了一个服务service接口，可以通过URL调用json服务。 修改后的新浪search的服务代码如下： 4.构造mobl界面 还后通过上面的trends服务，构造话题首页： 在通过search服务，构造微博结果显示页。 基本上就搞定了，打包上传到PhoneGap，一个微博应用就新鲜出炉了。 通过浏览器，可以在这里试用一下。在Andriod上跑的界面大概是这个样子。 全部代码如下： 更新： @很潮的猪头哥贡献了一张在iphone上访问的效果图片。]]></description>
			<content:encoded><![CDATA[<h3>1.mobl上的twitter trends例子</h3>
<p>mobl上关于<a href="http://docs.mobl-lang.org/tutorial/twittertrends">twitter trends的这个例子</a>，还是蛮好玩的。通过调用twitter的API，得到当下twitter上流行的话题。然后再根据每个话题，显示出最近这个话题的tweets。</p>
<div>
<img src="http://www.mobl-lang.org/wp-content/uploads/2011/01/Screen-shot-2011-01-17-at-7.26.35-PM-159x300.png" alt="" /><br />
<img src="http://www.mobl-lang.org/wp-content/uploads/2011/01/Screen-shot-2011-01-17-at-9.33.42-PM-159x300.png" alt="" />
</div>
<h3>2.mobl上的twitter trends例子</h3>
<p>照猫画虎，来试试做一个新浪微博的类似应用。查了一下微博的API，遗憾的发现关于话题的API还都处于beta状态。而且要用户登录以后才能调用，不像twitter在不登录的情况下就能调用trends类的API。<br />
新浪微博只有<a href="http://open.t.sina.com.cn/wiki/index.php/Search">Search类的API</a>有不登录调用的API，我们就拿search模拟一下吧。<br />
<span id="more-701"></span></p>
<pre class="brush: jscript; title: ; notranslate">

http://api.t.sina.com.cn/search.json?source=xxx&#038;rpp=100&#038;q=sugarcrm
</pre>
<h3>3.使用mobl的服务调用json</h3>
<p>mobl提供了一个服务service接口，可以通过URL调用json服务。<br />
修改后的新浪search的服务代码如下：</p>
<pre class="brush: jscript; title: ; notranslate">
service Twitter {
  resource trends() : JSON {
    uri = &quot;http://me.leonzhang.com/mobl/weibotrends/trendsjson.php&quot;
    encoding = &quot;jsonp&quot;
    mapper = trendsMapper
  }

  resource search(query : String) : JSON {
    //主要要把xxx改成你自己的api key
    uri = &quot;http://api.t.sina.com.cn/search.json?source=xxx&amp;rpp=200&amp;q=&quot; + query
    encoding = &quot;jsonp&quot;
    mapper = tweetsMapper
  }
}
</pre>
<h3>4.构造mobl界面</h3>
<p>还后通过上面的trends服务，构造话题首页：</p>
<pre class="brush: jscript; title: ; notranslate">
  header(_(&quot;Twitter trends&quot;))
  var trends = async(Twitter.trends())
  whenLoaded(trends) {
    group {
      list(topic in trends) {
        item(onclick={ search(topic.name); }) {
		  label(topic.name)
		}
      }
    }
  }
</pre>
<p>在通过search服务，构造微博结果显示页。</p>
<pre class="brush: jscript; title: ; notranslate">
screen search(query : String) {
  header(query) {
    backButton()
  }
  var results = async(Twitter.search(query))
  whenLoaded(results) {
    list(tweet in results) {
      block(tweetStyle) {
        image(tweet.profile_image_url,
              style=tweetIconStyle)
        &lt;b&gt;label(tweet.from_user) &quot;: &quot;&lt;/b&gt;
        label(tweet.text)
      }
    }
  }
}
</pre>
<p>基本上就搞定了，打包上传到<a href="http://www.phonegap.com/">PhoneGap</a>，一个微博应用就新鲜出炉了。<br />
通过浏览器，可以<a href="http://me.leonzhang.com/mobl/weibotrends/">在这里试用一下</a>。在Andriod上跑的界面大概是这个样子。<br />
<a href="http://www.flickr.com/photos/hileon/5557281164/" title="mobl with weibo 01 by hileonzhang, on Flickr"><img src="http://farm6.static.flickr.com/5291/5557281164_436b7e8230.jpg" width="236" height="431" alt="mobl with weibo 01" /></a><br />
<a href="http://www.flickr.com/photos/hileon/5557281564/" title="mobl with weibo 02 by hileonzhang, on Flickr"><img src="http://farm6.static.flickr.com/5296/5557281564_2ca305a12c.jpg" width="236" height="433" alt="mobl with weibo 02" /></a><br />
<a href="http://www.flickr.com/photos/hileon/5557282004/" title="mobl with weibo 03 by hileonzhang, on Flickr"><img src="http://farm6.static.flickr.com/5131/5557282004_abb4ccb639.jpg" width="236" height="434" alt="mobl with weibo 03" /></a></p>
<p>全部代码如下：</p>
<pre class="brush: jscript; title: ; notranslate">
application weibotrends

import mobl
import mobl::ui::generic
import mobl::ui::stylemixin

// STYLES
style tweetStyle {
  padding: 10px;
  margin: 5px;
  min-height: 50px;
  background-color: white;
  border: 1px solid #444;
  borderRadiusMixin(10px);
}

style tweetIconStyle {
  float: left;
  margin: 0 10px 0 0;
}

// TYPES
type Trend {
  name : String
  url  : String
}

type Tweet {
  profile_image_url : String
  created_at        : String
  from_user         : String
  text              : String
}

// LOGIC
function trendsMapper(json : JSON) : [Trend] {
  return json.trends;
}

function tweetsMapper(json : JSON) : [Tweet] {
  return json.results;
}

// SERVICE
service Twitter {
  resource trends() : JSON {
    uri = &quot;http://me.leonzhang.com/mobl/weibotrends/trendsjson.php&quot;
    encoding = &quot;jsonp&quot;
    mapper = trendsMapper
  }

  resource search(query : String) : JSON {
  	//注意要换成自己的新浪微博API key
    uri = &quot;http://api.t.sina.com.cn/search.json?source=xxx&amp;rpp=200&amp;q=&quot; + query
    encoding = &quot;jsonp&quot;
    mapper = tweetsMapper
  }
}

// UI
screen root() {
  script {
  	  fetchLanguageBundle(&quot;zh.json&quot;);
  	}

  header(_(&quot;Twitter trends&quot;))
  var trends = async(Twitter.trends())
  whenLoaded(trends) {
    group {
      list(topic in trends) {
        item(onclick={ search(topic.name); }) {
		  label(topic.name)
		}
      }
    }
  }
}

screen search(query : String) {
  header(query) {
    backButton()
  }
  var results = async(Twitter.search(query))
  whenLoaded(results) {
    list(tweet in results) {
      block(tweetStyle) {
        image(tweet.profile_image_url,
              style=tweetIconStyle)
        &lt;b&gt;label(tweet.from_user) &quot;: &quot;&lt;/b&gt;
        label(tweet.text)
      }
    }
  }
}
</pre>
<p>更新：<br />
<a href="http://t.sina.com.cn/siyangbi">@很潮的猪头哥</a>贡献了一张<a href="http://t.sina.com.cn/1864596981/zF4kBLneip">在iphone上访问的效果图片</a>。<br />
<img src="http://ww3.sinaimg.cn/bmiddle/6f237df5jw6dfkkz1xcczj.jpg" alt="" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.leonzhang.com/2011/03/25/mobl-weibo-search/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>通过phonegap把mobl应用发布各手机平台</title>
		<link>http://www.leonzhang.com/2011/03/18/deliver_mobl_app_to_android/</link>
		<comments>http://www.leonzhang.com/2011/03/18/deliver_mobl_app_to_android/#comments</comments>
		<pubDate>Fri, 18 Mar 2011 15:09:50 +0000</pubDate>
		<dc:creator>leon</dc:creator>
				<category><![CDATA[软件开发]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[ios]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mobl]]></category>
		<category><![CDATA[PhoneGap]]></category>
		<category><![CDATA[移动开发]]></category>

		<guid isPermaLink="false">http://www.leonzhang.com/?p=697</guid>
		<description><![CDATA[1.PhoneGap是干什么的？ PhoneGap同样也是多平台手机开发工具，它能把你的web应用打包成各各手机平台的本地应用。 打包iPhone应用需要Mac系统，还需要Apple的开发执照。我都没有，只能望洋兴叹了。 打包Android应用没有这些先决条件，咱们就试试这个吧。 2.准备mobl应用 还是拿小小计算器程序为例，mobl项目编译出来的结果在项目下的www目录里。 我们进入这个目录，把TipCalculator.html改名成index.html。 然后把整个www目录通过压缩工具打包成zip格式。 准备工作就完成了。 3.使用phonegap的在线发布工具phonegap build 到PhoneGap的在线发布工具phonegap build网站，点击“New App”新建一个应用，输入应用名称。 选择“upload an archive or index.html file”，上传我们前面做的那个zip压缩包。 等一会程序就打包好了。 4.下载apk在我的华为C8600上试试 下载打包好的apk文件，通过豌豆荚安装到Android平台的华为C8600上。 运行一下还挺像那么回事的。虽然速度慢了点，但是你也知道，C8600的速度本来就不咋地。 至此我们能通过mobl构建一个真正的Android手机应用了。 现在是功能还很简单，但是慢慢来嘛，mobl的功能也在不断增加中。]]></description>
			<content:encoded><![CDATA[<h2>1.PhoneGap是干什么的？</h2>
<p><a href="http://www.phonegap.com">PhoneGap</a>同样也是多平台手机开发工具，它能把你的web应用打包成各各手机平台的本地应用。<br />
打包iPhone应用需要Mac系统，还需要Apple的开发执照。我都没有，只能望洋兴叹了。<br />
打包Android应用没有这些先决条件，咱们就试试这个吧。</p>
<h2>2.准备mobl应用</h2>
<p>还是拿<strong>小小计算器</strong>程序为例，mobl项目编译出来的结果在项目下的<strong>www</strong>目录里。<br />
我们进入这个目录，把<strong>TipCalculator.html</strong>改名成<strong>index.html</strong>。<br />
然后把整个<strong>www</strong>目录通过压缩工具打包成zip格式。<br />
准备工作就完成了。<br />
<span id="more-697"></span></p>
<h2>3.使用phonegap的在线发布工具phonegap build</h2>
<p>到<a href="http://www.phonegap.com">PhoneGap</a>的在线发布工具<a href="https://build.phonegap.com/apps">phonegap build</a>网站，点击“New App”新建一个应用，输入应用名称。<br />
选择“upload an archive or index.html file”，上传我们前面做的那个zip压缩包。<br />
<a href="http://www.flickr.com/photos/hileon/5537523112/" title="mobl with phonegap02 by hileonzhang, on Flickr"><img src="http://farm6.static.flickr.com/5020/5537523112_982c978a4d.jpg" width="500" height="279" alt="mobl with phonegap02" /></a></p>
<p>等一会程序就打包好了。<br />
<a href="http://www.flickr.com/photos/hileon/5537523158/" title="mobl with phonegap01 by hileonzhang, on Flickr"><img src="http://farm6.static.flickr.com/5057/5537523158_fe7450301e.jpg" width="500" height="154" alt="mobl with phonegap01" /></a></p>
<h2>4.下载apk在我的华为C8600上试试</h2>
<p>下载打包好的apk文件，通过<a href="http://wandoujia.com/">豌豆荚</a>安装到Android平台的华为C8600上。<br />
运行一下还挺像那么回事的。虽然速度慢了点，但是你也知道，C8600的速度本来就不咋地。<br />
<a href="http://www.flickr.com/photos/hileon/5537523734/" title="mobl in andriod01 by hileonzhang, on Flickr"><img src="http://farm6.static.flickr.com/5299/5537523734_45ed5a0899.jpg" width="236" height="428" alt="mobl in andriod01" /></a><br />
<a href="http://www.flickr.com/photos/hileon/5536946047/" title="mobl in andriod02 by hileonzhang, on Flickr"><img src="http://farm6.static.flickr.com/5131/5536946047_87824a9821.jpg" width="236" height="428" alt="mobl in andriod02" /></a><br />
<a href="http://www.flickr.com/photos/hileon/5536946299/" title="mobl in andriod03 by hileonzhang, on Flickr"><img src="http://farm6.static.flickr.com/5056/5536946299_551c2b831e.jpg" width="236" height="428" alt="mobl in andriod03" /></a><br />
<a href="http://www.flickr.com/photos/hileon/5536945523/" title="mobl in andriod04 by hileonzhang, on Flickr"><img src="http://farm6.static.flickr.com/5097/5536945523_d5c3e93101.jpg" width="236" height="428" alt="mobl in andriod04" /></a></p>
<p>至此我们能通过mobl构建一个真正的Android手机应用了。<br />
现在是功能还很简单，但是慢慢来嘛，mobl的功能也在不断增加中。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.leonzhang.com/2011/03/18/deliver_mobl_app_to_android/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>美化mobl应用界面</title>
		<link>http://www.leonzhang.com/2011/03/17/style-mobl-ui/</link>
		<comments>http://www.leonzhang.com/2011/03/17/style-mobl-ui/#comments</comments>
		<pubDate>Thu, 17 Mar 2011 14:28:20 +0000</pubDate>
		<dc:creator>leon</dc:creator>
				<category><![CDATA[软件开发]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[ios]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mobl]]></category>
		<category><![CDATA[移动开发]]></category>

		<guid isPermaLink="false">http://www.leonzhang.com/?p=692</guid>
		<description><![CDATA[1.派生mobl界面模块 接着上次我的的”小小计算器”程序。为了修改它的界面风格，我们首先派生一个mobl的模块。 新建一个叫ui.mobl的文件，在里面输入下面两行代码。第一句的意思是新建的模块名叫ui，第二句的意思是ui模块导入所有mobl::ui::generic的内容（开始我还以为mixin是中文迷信的拼音呢！搞了半天是mix in。唉英文差害死人）。 回到tipcalculator.mobl文件，现在可以把里面引用mobl::ui::generic的那句改成引用ui了。 2.使用从mobl::ui::generic导入的变量 OK，准备功能完毕。现在在ui.mobl里就可以使用或者重写mobl::ui::generic里定义的变量了。 比如mobl::ui::generic里的样式变量（样式变量都是以$开头的）$baseColor，它代表了当前界面的基础色。另外里面还定义了$baseColor,$baseColorGreen，$baseColorRed, $baseColorRedish等颜色。 为了修改当前界面的基础色，只要输入下面一句，界面基础色就变成红的了。 当然我们也可以使用mobl::ui::generic里的rgb函数，比如这样整个界面就变成灰的了。这里有关于具体模块内功能的描述，但是似乎文档还不太全面。 3.使用自定义css样式表 我们也可以定义新的样式变量，语法是css的扩展，据说是借鉴了scss的很多特性。 下面定义了两个新的样式变量，相信用过css的应该都能看懂。 但是有一点我没明白，为什么这些变量不再以$开头了呢？而且我换成$还编译不通过。 现在再打开tipcalculator.mobl文件,把里面的按钮使用我们新定义的样式变量。代码如下，效果见后面的图。 运行效果可以看这里.]]></description>
			<content:encoded><![CDATA[<h2>1.派生mobl界面模块</h2>
<p>接着上次我的的”小小计算器”程序。为了修改它的界面风格，我们首先派生一个mobl的模块。<br />
新建一个叫<strong>ui.mobl</strong>的文件，在里面输入下面两行代码。第一句的意思是新建的模块名叫<strong>ui</strong>，第二句的意思是<strong>ui</strong>模块导入所有<strong>mobl::ui::generic</strong>的内容（开始我还以为mixin是中文迷信的拼音呢！搞了半天是mix in。唉英文差害死人）。</p>
<pre class="brush: jscript; title: ; notranslate">
module ui
mixin mobl::ui::generic
</pre>
<p>回到<strong>tipcalculator.mobl</strong>文件，现在可以把里面引用<strong>mobl::ui::generic</strong>的那句改成引用<strong>ui</strong>了。</p>
<pre class="brush: jscript; title: ; notranslate">
//import mobl::ui::generic
import ui
</pre>
<p><img src="http://www.mobl-lang.org/wp-content/uploads/2011/01/Screen-shot-2011-01-14-at-12.59.06-PM-159x300.png" alt="" /></p>
<h2>2.使用从mobl::ui::generic导入的变量</h2>
<p>OK，准备功能完毕。现在在<strong>ui.mobl</strong>里就可以使用或者重写<strong>mobl::ui::generic</strong>里定义的变量了。<br />
比如<strong>mobl::ui::generic</strong>里的样式变量（<em>样式变量都是以$开头的</em>）$baseColor，它代表了当前界面的基础色。另外里面还定义了$baseColor,$baseColorGreen，$baseColorRed, $baseColorRedish等颜色。<br />
为了修改当前界面的基础色，只要输入下面一句，界面基础色就变成红的了。</p>
<pre class="brush: jscript; title: ; notranslate">
style $baseColor = $baseColoRed
</pre>
<p>当然我们也可以使用<strong>mobl::ui::generic</strong>里的<strong>rgb</strong>函数，比如这样整个界面就变成灰的了。<a href="http://docs.mobl-lang.org/">这里</a>有关于具体模块内功能的描述，但是似乎文档还不太全面。</p>
<pre class="brush: jscript; title: ; notranslate">
style $baseColor = rgb(100, 100, 100)
</pre>
<p><img src="http://www.mobl-lang.org/wp-content/uploads/2011/01/Screen-shot-2011-01-14-at-1.03.04-PM-159x300.png" alt="" /></p>
<h2>3.使用自定义css样式表</h2>
<p>我们也可以定义新的样式变量，语法是css的扩展，据说是借鉴了<a href="http://sass-lang.com/">scss</a>的很多特性。<br />
下面定义了两个新的样式变量，相信用过css的应该都能看懂。<br />
但是有一点我没明白，为什么这些变量不再以$开头了呢？而且我换成$还编译不通过。</p>
<pre class="brush: jscript; title: ; notranslate">
style mixin myButtonStyleMixin($fromColor, $toColor) {
  border: 1px solid #000;
  padding: 10px;
  line-height: 3em;
  margin: 5px;
  borderRadiusMixin(5px);
  backgroundGradientMixin($fromColor, $toColor);
}

style myButtonStyle {
  myButtonStyleMixin(#ddd, #bbb);
}

style myButtonPushedStyle {
  myButtonStyleMixin(#aaa, #999);
}
</pre>
<p>现在再打开<strong>tipcalculator.mobl</strong>文件,把里面的按钮使用我们新定义的样式变量。代码如下，效果见后面的图。</p>
<pre class="brush: jscript; title: ; notranslate">
		button(_(&quot;Click me&quot;), style=myButtonStyle,
                   pushedStyle=myButtonPushedStyle, onclick={
		  alert(_(&quot;You clicked me!&quot;));
		})
</pre>
<p><img src="http://www.mobl-lang.org/wp-content/uploads/2011/01/Screen-shot-2011-01-14-at-1.37.11-PM.png" alt="" /></p>
<p>运行效果可以看<a href="http://me.leonzhang.com/mobl/TipCalculator/TipCalculator.html">这里</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.leonzhang.com/2011/03/17/style-mobl-ui/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>在mobl里显示中文</title>
		<link>http://www.leonzhang.com/2011/03/16/%e5%9c%a8mobl%e9%87%8c%e6%98%be%e7%a4%ba%e4%b8%ad%e6%96%87/</link>
		<comments>http://www.leonzhang.com/2011/03/16/%e5%9c%a8mobl%e9%87%8c%e6%98%be%e7%a4%ba%e4%b8%ad%e6%96%87/#comments</comments>
		<pubDate>Wed, 16 Mar 2011 15:57:22 +0000</pubDate>
		<dc:creator>leon</dc:creator>
				<category><![CDATA[软件开发]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mobl]]></category>

		<guid isPermaLink="false">http://www.leonzhang.com/?p=682</guid>
		<description><![CDATA[昨天的blog里说mobl的IDE不支持中文输入，Zef回复说现在可以通过使用语言文件的方式显示中文，IDE的下一个版本里将解决这个问题。 首先看看mobl的语言文件是什么？ 很多php程序都有自己格式的语言文件，一般就是普通的php文件，比如SugarCRM就是以php数组存放语言文件。Linux里的应用程序通常使用gettext来实现国际化。StatusNet就是采取这种方式。 mobl是主要使用web前台技术，内容一般通过javascript动态产生，国际化也是通过javascript调用json格式的文件来实现的。 这是一个简单的不能再简单的mobl的json语言文件： 再看看怎么使用这个语言文件 以小小计算器程序为例，打开TipCalculator.mobl文件。 首先在开头引用“import mobl”，i18n用到的方式在这个包里。 然后通过“fetchLanguageBundle(“zh.json”);”把json语言文件导入。 最后把原来使用字符串的地方，应“_()”函数包起来就得了。（“_()”好像Drupal呀。） 修改后的TipCalculator.mobl文件如下： 完成后的程序，可以在这里测试。 好了虽然能支持中文了，但是还是希望早日用上支持中文的mobl IDE。]]></description>
			<content:encoded><![CDATA[<p>昨天的blog里说<a href="http://www.mobl-lang.org">mobl</a>的IDE不支持中文输入，<a href="http://zef.me/">Zef</a>回复说现在可以通过使用语言文件的方式显示中文，IDE的下一个版本里将解决这个问题。</p>
<h2>首先看看mobl的语言文件是什么？</h2>
<p>很多php程序都有自己格式的语言文件，一般就是普通的php文件，比如<a href="http://www.sugarcrm.com">SugarCRM</a>就是以php数组存放语言文件。Linux里的应用程序通常使用<a href="http://www.poedit.net/index.php">gettext</a>来实现国际化。<a href="http://status.net/">StatusNet</a>就是采取这种方式。<br />
<a href="http://www.mobl-lang.org">mobl</a>是主要使用web前台技术，内容一般通过javascript动态产生，国际化也是通过javascript调用json格式的文件来实现的。<br />
这是一个简单的不能再简单的mobl的json语言文件：</p>
<pre class="brush: jscript; title: ; notranslate">
{
	&quot;Tip calculator&quot;:&quot;小小计算器&quot;,
	&quot;Click me&quot;:&quot;点我&quot;,
	&quot;You clicked me!&quot;:&quot;被你点了&quot;
}
</pre>
<h2>再看看怎么使用这个语言文件</h2>
<p>以小小计算器程序为例，打开TipCalculator.mobl文件。<br />
首先在开头引用“import mobl”，i18n用到的方式在这个包里。<br />
然后通过“fetchLanguageBundle(“zh.json”);”把json语言文件导入。<br />
最后把原来使用字符串的地方，应“_()”函数包起来就得了。（“_()”好像Drupal呀。）<br />
修改后的TipCalculator.mobl文件如下：</p>
<pre class="brush: jscript; title: ; notranslate">
application TipCalculator

import mobl
import mobl::ui::generic

screen root() {
	script {
  	  fetchLanguageBundle(&quot;zh.json&quot;);
  	}

	var amount     =  20
  	var percentage =  10

  	header(_(&quot;Tip calculator&quot;))
  	group {
	    item { numField(amount, label=&quot;amount&quot;) }
	    item { numField(percentage, label=&quot;percentage&quot;) }
	    item { &quot;$&quot; label(amount * (1 + percentage/100)) }
	}
	group{
		button(_(&quot;Click me&quot;), onclick={
		  alert(_(&quot;You clicked me!&quot;));
		})
	}
}
</pre>
<p>完成后的程序，可以在<a href="http://me.leonzhang.com/mobl/TipCalculator/TipCalculator.html">这里</a>测试。</p>
<p>好了虽然能支持中文了，但是还是希望早日用上支持中文的mobl IDE。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.leonzhang.com/2011/03/16/%e5%9c%a8mobl%e9%87%8c%e6%98%be%e7%a4%ba%e4%b8%ad%e6%96%87/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>mobl-新颖的移动设备应用开发工具</title>
		<link>http://www.leonzhang.com/2011/03/16/mobl-mobile-develope-tool/</link>
		<comments>http://www.leonzhang.com/2011/03/16/mobl-mobile-develope-tool/#comments</comments>
		<pubDate>Tue, 15 Mar 2011 23:41:17 +0000</pubDate>
		<dc:creator>leon</dc:creator>
				<category><![CDATA[软件开发]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[ios]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mobl]]></category>
		<category><![CDATA[移动开发]]></category>

		<guid isPermaLink="false">http://www.leonzhang.com/?p=661</guid>
		<description><![CDATA[mobl是什么 mobl 是一个套手机应用开发工具（有自己界面描述语言+编译工具，提供基于Eclilpse的IDE）。完全基于标准web技术(Html+Css+javascript)，可以快速开发手机应用程序，跨平台，支持包括 iOS、Android 和其他支持 HTML5 技术的手机。 优势 适合各种支持html5和javascript手机平台 开发就是基于web技术,对平台相关的知识需求很少,入手快 劣势 不能完全访问移动设备的很多本地特性 没有native的app好用,好看 helloworld 从这里下载mobl的开发工具以后。通过Eclipse自动生成一个”mobl project”项目，保存一个简单的应用程序就完成了。生成的代码如下： 界面效果是这样的，实际使用效果可以用手机或者支持html5的浏览器直接访问这个页面。 小小计算器 这是一个简单的计算器应用。输入是一个数字和一个百分数，输出是这两个数字乘出来的结果。所有的代码如下： 界面效果是这样的，实际使用效果可以用手机或者支持html5的浏览器直接访问这个页面。 碰到的问题 现在做出来的就是个web应用,如何包装成本地应用,如何发布到app store? 中文支持有些问题,在IDE中输入中文会导致编译不通过.但是只是在IDE环境中,直接编辑.mobl文件,通过命令行编译器编译没有问题. 后记 总体来看，使用mobl开发简单的应用速度非常快，语法很简洁。其他的还不太清楚，日后再看。 我不懂移动开发，但是发现mobl还是挺好玩的。欢迎熟悉移动开发的朋友多指正。]]></description>
			<content:encoded><![CDATA[<h2>mobl是什么</h2>
<p>mobl 是一个套手机应用开发工具（有自己界面描述语言+编译工具，提供基于Eclilpse的IDE）。完全基于标准web技术(Html+Css+javascript)，可以快速开发手机应用程序，跨平台，支持包括 iOS、Android 和其他支持 HTML5 技术的手机。</p>
<h2>优势</h2>
<ul>
<li>适合各种支持html5和javascript手机平台</li>
<li>开发就是基于web技术,对平台相关的知识需求很少,入手快</li>
</ul>
<h2>劣势</h2>
<ul>
<li>不能完全访问移动设备的很多本地特性</li>
<li>没有native的app好用,好看</li>
</ul>
<h2>helloworld</h2>
<p>从这里<a href="http://www.mobl-lang.org/get/">下载</a>mobl的开发工具以后。通过Eclipse自动生成一个”mobl project”项目，保存一个简单的应用程序就完成了。生成的代码如下：</p>
<pre class="brush: jscript; title: ; notranslate">
application hellomobl

import mobl::ui::generic

screen root() {
	header(&quot;Hello world&quot;)
}
</pre>
<p>界面效果是这样的，实际使用效果可以用手机或者支持html5的浏览器直接访问<a href="http://me.leonzhang.com/mobl/hellomobl/hellomobl.html">这个页面</a>。<br />
<img src="http://www.mobl-lang.org/wp-content/uploads/2011/01/helloworld-159x300.png" alt="" /></p>
<h2>小小计算器</h2>
<p>这是一个<a href="http://docs.mobl-lang.org/tutorial/tipcalculator/">简单的计算器</a>应用。输入是一个数字和一个百分数，输出是这两个数字乘出来的结果。所有的代码如下：</p>
<pre class="brush: jscript; title: ; notranslate">
application TipCalculator

import ui

screen root() {
	var amount     =  20  //定义两个变量
  	var percentage =  10

  	header(&quot;Tip calculator&quot;) //标题
  	group {
	    item { numField(amount, label=&quot;amount&quot;) } //把变量amount与数字输入控件绑定
	    item { numField(percentage, label=&quot;percentage&quot;) } //把变量percentage与数字输入控件绑定
	    item { &quot;$&quot; label(amount * (1 + percentage/100)) } //根据这两个变量，计算，通过标签控件输出
	}
}
</pre>
<p>界面效果是这样的，实际使用效果可以用手机或者支持html5的浏览器直接访问<a href="http://hydra.nixos.org/build/850237/download/1/www/">这个页面</a>。<br />
<img src="http://www.mobl-lang.org/wp-content/uploads/2011/01/tipcalculator-159x300.png" alt="" /></p>
<h2>碰到的问题</h2>
<ul>
<li>现在做出来的就是个web应用,如何包装成本地应用,如何发布到app store?</li>
<li>中文支持有些问题,在IDE中输入中文会导致编译不通过.但是只是在IDE环境中,直接编辑.mobl文件,通过<a href="http://docs.mobl-lang.org/cli">命令行编译器</a>编译没有问题.</li>
</ul>
<h2>后记</h2>
<p>总体来看，使用mobl开发简单的应用速度非常快，语法很简洁。其他的还不太清楚，日后再看。<br />
我不懂移动开发，但是发现mobl还是挺好玩的。欢迎熟悉移动开发的朋友多指正。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.leonzhang.com/2011/03/16/mobl-mobile-develope-tool/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>讨厌的CSS3前缀</title>
		<link>http://www.leonzhang.com/2011/03/04/bad_css3_prefi/</link>
		<comments>http://www.leonzhang.com/2011/03/04/bad_css3_prefi/#comments</comments>
		<pubDate>Fri, 04 Mar 2011 05:12:47 +0000</pubDate>
		<dc:creator>leon</dc:creator>
				<category><![CDATA[软件开发]]></category>
		<category><![CDATA[css]]></category>

		<guid isPermaLink="false">http://www.leonzhang.com/?p=649</guid>
		<description><![CDATA[CSS3确实带来了很多很炫的功能,但是为了在现在的浏览器上使用CSS3确实很费劲. 比如要为不同的浏览器书写自己格式的CSS3属性名就是一件麻烦事. 他们为什么不直接使用标准的CSS3属性名呢?! 如果要把元素旋转度,CSS3的语法是: 却要写这么多: 真是够丑的,谁有好办法?]]></description>
			<content:encoded><![CDATA[<p>CSS3确实带来了很多很炫的功能,但是为了在现在的浏览器上使用CSS3确实很费劲.<br />
比如要为不同的浏览器书写自己格式的CSS3属性名就是一件麻烦事.<br />
他们为什么不直接使用标准的CSS3属性名呢?!</p>
<p>如果要把元素旋转度,CSS3的语法是:</p>
<pre class="brush: css; title: ; notranslate">transform:rotate(-3deg);</pre>
<p>却要写这么多:</p>
<pre class="brush: css; title: ; notranslate">
   -webkit-transform:rotate(-3deg); /*为Chrome/Safari*/
   -moz-transform:rotate(-3deg); /*为Firefox*/
   -ms-transform:rotate(-3deg); /*为IE*/
   -o-transform:rotate(-3deg); /*为Opera*/
   transform:rotate(-3deg); /*为nothing*/
</pre>
<p>真是够丑的,谁有好办法?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.leonzhang.com/2011/03/04/bad_css3_prefi/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>创新的8个挑战</title>
		<link>http://www.leonzhang.com/2010/11/02/8_challenges_of_innovation/</link>
		<comments>http://www.leonzhang.com/2010/11/02/8_challenges_of_innovation/#comments</comments>
		<pubDate>Tue, 02 Nov 2010 04:31:03 +0000</pubDate>
		<dc:creator>leon</dc:creator>
				<category><![CDATA[软件开发]]></category>
		<category><![CDATA[innovation]]></category>
		<category><![CDATA[startup]]></category>
		<category><![CDATA[创业]]></category>

		<guid isPermaLink="false">http://www.leonzhang.com/?p=574</guid>
		<description><![CDATA[1. 发现想法 想法来源广泛，专注研究、白日梦、个人问题、观察其他人、偶然事故、学习等等等等。想法可能是一个我们自己认为值得解决的问题，或者仅仅是我们感兴趣的一个小实验。 2. 找到解决之道 想法是一回事，解决之道是另一回事。解决之道需要比想法付出更多的努力，而且除了不断尝试，很难知道什么时候够了。通常在寻找#1的解决之道的过程中，需要找到更多的小的想法的解决之道。还有一种可能是，把#1的想法应用到一个更加细分、更加垂直的领域。 3. 寻找资助 现在我们有了想法和解决之道，我们需要付诸实施了，我们需要资助、需要开启创业之门。这是一个寻找共同创始人或者资助者，然后与他们共事，让他们满意的过程。 4. 低成本量产 我常听朋友说，做硅片中国的技术不比欧美差，但是批量生产就不是那么回事了，我们就落后太多了。做一件容易，做1000件一样的、同等质量的就难上加难了。对软件服务来说，就是服务一个人、一个公司容易，如果从服务一个平滑扩展到服务一千、一万、百万、千万个，并保证较低的成本，那就难了。 低成本同时也带来另外一个问题，就是别人的复制成本也低。也就也意味着提供同样服务的竞争者也会很多，我们会不会被淹没在茫茫噪声之中。 5. 寻找潜在客户 没人用的产品什么都不是！有些创新可能被埋藏几十年，直到有人找到方法让这个创新找到适用的人群。 6. 击败竞争对手 刚在微博上说“创新的8个挑战”，马上就有高人指出“发现一个腾讯等自律的的公司copy不了的想法”最重要。是的不存在理想的蓝海，永远有人也能想法我们的想法，也许我们的想法本来就是从别人那里copy来的。那些大公司也总是会有一眼瞄着，伺机而动。 7. 正确的时机 这个最炫，我们永远不知道现在的时机对不对，人们能不能接受我们的想法。所以创新的产品通常需要拿一些现有的产品做类比，让人更容易接受。所以我们会看到，汽车的动力用“马力”表示，电灯的亮度用“支光”表示。 8. 活下来 好吧，就算前面#1～7我们都做的很好，我们还是会需要付房租、电费、工资&#8230;。也许你的运气好，政府或者别人会给你一些优惠和赞助，但是那些能让你走多远？活下去，靠销售我们自己的产品支持我们活下去，成功就到来了。 以上内容摘自]]></description>
			<content:encoded><![CDATA[<p><strong>1. 发现想法</strong><br />
  想法来源广泛，专注研究、白日梦、个人问题、观察其他人、偶然事故、学习等等等等。想法可能是一个我们自己认为值得解决的问题，或者仅仅是我们感兴趣的一个小实验。<br />
<strong>2. 找到解决之道</strong><br />
  想法是一回事，解决之道是另一回事。解决之道需要比想法付出更多的努力，而且除了不断尝试，很难知道什么时候够了。通常在寻找#1的解决之道的过程中，需要找到更多的小的想法的解决之道。还有一种可能是，把#1的想法应用到一个更加细分、更加垂直的领域。<br />
<strong>3. 寻找资助</strong><br />
  现在我们有了想法和解决之道，我们需要付诸实施了，我们需要资助、需要开启创业之门。这是一个寻找共同创始人或者资助者，然后与他们共事，让他们满意的过程。<br />
<strong>4. 低成本量产</strong><br />
  我常听朋友说，做硅片中国的技术不比欧美差，但是批量生产就不是那么回事了，我们就落后太多了。做一件容易，做1000件一样的、同等质量的就难上加难了。对软件服务来说，就是服务一个人、一个公司容易，如果从服务一个平滑扩展到服务一千、一万、百万、千万个，并保证较低的成本，那就难了。<br />
  低成本同时也带来另外一个问题，就是别人的复制成本也低。也就也意味着提供同样服务的竞争者也会很多，我们会不会被淹没在茫茫噪声之中。<br />
<strong>5. 寻找潜在客户</strong><br />
  没人用的产品什么都不是！有些创新可能被埋藏几十年，直到有人找到方法让这个创新找到适用的人群。<br />
<strong>6. 击败竞争对手</strong><br />
  刚在微博上说“创新的8个挑战”，马上就有高人指出“<a href="http://t.sina.com.cn/1762647817/wr0sGkButg">发现一个腾讯等自律的的公司copy不了的想法</a>”最重要。是的不存在理想的蓝海，永远有人也能想法我们的想法，也许我们的想法本来就是从别人那里copy来的。那些大公司也总是会有一眼瞄着，伺机而动。<br />
<strong>7. 正确的时机</strong><br />
  这个最炫，我们永远不知道现在的时机对不对，人们能不能接受我们的想法。所以创新的产品通常需要拿一些现有的产品做类比，让人更容易接受。所以我们会看到，汽车的动力用“马力”表示，电灯的亮度用“支光”表示。<br />
<strong>8. 活下来</strong><br />
好吧，就算前面#1～7我们都做的很好，我们还是会需要付房租、电费、工资&#8230;。也许你的运气好，政府或者别人会给你一些优惠和赞助，但是那些能让你走多远？活下去，靠销售我们自己的产品支持我们活下去，成功就到来了。</p>
<p>以上内容摘自<a href="http://book.douban.com/subject/5285710/"><br />
<img src="http://img5.douban.com/lpic/s4480325.jpg" alt="The Myths of Innovation" /><br />
</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.leonzhang.com/2010/11/02/8_challenges_of_innovation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>升级StatusNet 0.9.2到0.9.3</title>
		<link>http://www.leonzhang.com/2010/07/03/upgrade_statusnet_from_092_to_093/</link>
		<comments>http://www.leonzhang.com/2010/07/03/upgrade_statusnet_from_092_to_093/#comments</comments>
		<pubDate>Fri, 02 Jul 2010 17:54:46 +0000</pubDate>
		<dc:creator>leon</dc:creator>
				<category><![CDATA[软件开发]]></category>
		<category><![CDATA[microblog]]></category>
		<category><![CDATA[StatusNet]]></category>

		<guid isPermaLink="false">http://www.leonzhang.com/?p=546</guid>
		<description><![CDATA[停止StatusNet网站 备份StatusNet 0.9.2 网站的所以文件和数据库！！！ 重命名StatusNet 0.9.2目录，比如从mblog改成mblog092 下载并解压StatusNet 0.9.3到mblog目录，修改目录权限 从mblog092目录拷贝下列文件到mblog目录 config.php .htaccess file\* avatar\* background\* 升级结束，开启网站，测试基本功能。]]></description>
			<content:encoded><![CDATA[<ol>
<li>停止StatusNet网站</li>
<li>备份StatusNet 0.9.2 网站的所以文件和数据库！！！</li>
<li>重命名StatusNet 0.9.2目录，比如从mblog改成mblog092</li>
<li>下载并解压StatusNet 0.9.3到mblog目录，修改目录权限</li>
<li>从mblog092目录拷贝下列文件到mblog目录</li>
<blockquote>
<ol>
<li>config.php</li>
<li>.htaccess</li>
<li>file\*</li>
<li>avatar\*</li>
<li>background\*</li>
</ol>
</blockquote>
<li>升级结束，开启网站，测试基本功能。</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.leonzhang.com/2010/07/03/upgrade_statusnet_from_092_to_093/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Page Caching using disk: basic
Database Caching 9/85 queries in 0.065 seconds using disk: basic
Object Caching 1393/1581 objects using disk: basic
Content Delivery Network via N/A

Served from: www.leonzhang.com @ 2012-02-10 19:40:23 -->
