Blog

  • Dart 1.5.3的一些变化

    Ashampoo_Snap_2014.07.15_22h13m10s_003_

    Dart是一个发展非常快速的语言。如今最新的版本是1.5.3。自从今年1月份我写了两篇关于Dart的文章( )以来,Dart语言本身,尤其是我用到的Polymer部分,有了很大的变化。

    为了准备8月9日(暂定)于苏州举行的,由G4P.ccGDG Suzhou联合举办的活动,我对之前编写的Dart小程序进行了调试。本文就在这次调试中发现的变化进行一些总结。

    一个Dart/Polymer程序的架构没有变化,还是由三部分组成:

    • 入口程序,比如getqotd.html。这个文件提供了页面的布局和对Polymer元素的调用。
    • Polymer元素模板,比如qotd.html。这个文件定义了一个Polymer元素的布局和一些基本设置。
    • Polymer元素的代码,比如qotd.dart。这个文件也是该Polymer元素的驱动代码部分,也可以是我们编写的一个Polymer/Dart程序的核心。

    入口程序

    <head>
      <meta charset=utf-8>
      <meta name=viewport content=width=device-width, initial-scale=1.0>
      <title>QOTD Sampe App</title>
      <script src=packages/web_components/platform.js></script>
      <script src=packages/web_components/dart_support.js></script>
      <!-- import the qotd -->
      <link rel=import href=qotd.html>
      <script type=application/dart>export 'package:polymer/init.dart';</script>
      <script src=packages/browser/dart.js></script>
      <link rel=stylesheet href=css/bootstrap.min.css>
    </head>

    这是一个标准的入口程序的HTML头部分。与之前相比,该部分加入了移动设备的支持。

    另外,所引用的JS文件也改为platform.jsdart_support.js。而原来的:<script type=application/dart>export 'package:polymer/init.dart';</script><script src=packages/browser/dart.js></script>已经被弃用。我个人对这个改变比较欢迎。毕竟原来的语句很不像HTML。

    模板

    重要的改变有两个。

    一个是在原先的<polymer-element>定义之前必须再加一个<link rel=import href=packages/polymer/polymer.html>语句。

    第二,鉴于Dart已经重新对shadow DOM进行了更好的支持,于是可以在<template>中直接加入对CSS的引用,如:<link type=text/css rel=stylesheet href=css/bootstrap.min.css>这样。

    代码

    鉴于上述的第二点,代码中原先需要的对shadowDOM进行applyAuthorStyles的操作就不再必要。事实上,如果你写了,Dart编译器会给出deprecated的警告。

    基本上我发现的改动就是这些。当然,改动肯定不止这些。我在O\’Reilly买了一本Dart: Up and Running的书,电子版已经更新并专列了一章介绍新的变换。我印象比较深的是Reflection的引入。

    本文收录于[go4pro.org]

  • 冬天的故事

    冬天的故事

    一开始看到《冬天的故事》这个名字的时候,还以为是莎翁的著作改编(维基链接:http://zh.wikipedia.org/wiki/%E5%86%AC%E5%A4%A9%E7%9A%84%E6%95%85%E4%BA%8B)。但是看完之后发现不是,而是改编自小说家马克·哈普林同名畅销小说。

    豆瓣对该片评价不高,只有区区5.4分,按照一般判断,基本属于烂片。但是在我看来,这是一本被低估的片子。

    从爱情的角度去探讨这本片子,是一个错误的角度。大家可以吐槽对爱情的描写过于单薄,但是20世纪初——乃至更早时期的爱情——就是这个样子。如果我们吐槽这里的爱情,就也要吐槽《悲惨世界》中珂赛特和马吕斯的一见钟情。

    50cdecb66d72632d26ac05ae28a0c3af

    片子讨论的是人生存最基本的问题:我在这个世界上到底要做什么?为了更好地展现这一主题,我们必须要有坏人,于是我们看到了拉塞尔·克劳和威尔·史密斯所代表的恶势力。他们的目的就是阻止正方对人类的救赎。正方的代表是带有使命的、落入人间的天使。

    天使的使命只有一个,完成使命后就会回到上天交差,其具象的表示就是变成天上的一颗星星。

    正是有了这样的设置,我们对其中出现的种种奇幻和超现实现象就不要太过惊奇和意外了。

    这是一个有着深厚宗教救赎背景的故事。当然,这样的故事完全可以在10年甚至更短的跨度内完成,而编剧特意将其延展到100年,无非是为了加强一种沧桑感和永恒感。时间跨度也不能再长了,否则Peter就不能再与小Willa见面。

    个人认为,如果这个故事的时间跨度不是设置在191X年到201X年,而是整体提前100年,从181X开始到191X结束,会弥补其过于超现实而带来的不真实感。

    有人评论说这本片子很黑暗。但其实根本不是如此。没有中世纪的仪式,有的只是中世纪的传说和童话。

    再回到要回答的问题:我在这个世界上到底要做什么?这是一个直指人心的拷问。影片通过一个具体的表征:使命以及世俗(所谓麻瓜)定义为“奇迹”的东西来试图解答这点。 Beverly的使命是让Peter永生(或者说在完成其使命前不会死并保持年轻),Peter的使命是拯救Abby。这些都是需要一个奇迹来完成的事情。而他们都做到了。使命是有因果关系的。如果Beverly没有完成使命,那么Peter也完不成使命,那么Abby就会死去。这种使命的承继正是使命高尚、伟大的根本原因所在。前仆后继,死而后已。

    Abby和小Willa见到Peter都要他抱,都问他Am I light or heavy?而Peter的回答也是Light as a feather. 100年的时间间隔又算得了什么呢?同样的不期而遇,同样的倾盖如故,同样的厚重的使命感,这才是影片要表述的核心。

    人生短暂,白驹过隙。正如我两年前写的《大鼻子情圣》的评论中说到的:

    抓住19世纪观众和评论家的心的,而且继续抓住了我们的心的,是故事讲述到的爱情、激情、英雄主义和道德荣誉感感人至深。 What captured the hearts of nineteenth-century readers and spectators, and continues to capture ours now, is the depth of the story’s love, passion, heroism, and moral honor.

    那么在其中加入“使命感”又有何妨呢?

  • 乐高,黑得漂亮

    昨天和老彼得看了乐高2014年的作品《乐高大电影》(The Lego Movies)。

    p2185400387

    我就不谈情节、效果、配乐之类的东西了。

    就一点,我要说,“乐高,黑得漂亮!”

    Ashampoo_Snap_2014.06.02_09h17m50s_002_

    一台声控的电脑,对“解除屏障”这么标准的指令无法理解,直到某人用非常不标准的口音说出“借 出 苹 张”的时候,电脑才完成了操作。

    这才是高级黑啊!

  • 锤子手机,不许用Win 8和其它

    最近有两个新闻要连起来看:

    1. 老罗发布了注定闻名于世的“锤子”手机,学名Smartisan T1。
    2. 中国政府正式宣布,在微软停止支持XP后,不会采用Windows 8操作系统。

    先说“锤子”——你说个锤子啊!

    老罗对苹果是有感情的。官方首页的风格、布局、乃至配色,都和苹果的官方首页有着惊人的类似。有图有真相:

    锤子手机官方首页

    苹果官方首页

    他很喜欢Windows Phone的界面,所以在基于Android的Smartisan OS上封装了类似Windows Phone的磁贴效果:

    锤子手机的界面

    其实Windows Phone还是很萌的,你们不要黑它。

    Windows的用户数量在目前还是巨大的,应用数量也是巨大的。Windows——或者说微软——的错误在于:太想整合桌面和手机了。所以我们才看到了一个Booming Jelly, She’s Congee(不明觉厉,细思恐极)的操作系统Windows 8。

    我一直说:手机端是信息消费端,桌面端是信息制造端。就像现在,我要开始写博客的时候,我根本不会考虑用手机(包括iPad)来写,甚至不会考虑用WEB端(Wordpress提供的后台)来写,而宁可用Live Writer来写。虽然说有些功能无法直接在此实现,有些信息无法再次直接嵌入,但我还是会用一个桌面端程序来写。

    微软的正确方向——我希望是在最近的1-2年之内,反正新换的CEO是有资格放火的呀——将桌面操作系统和手机操作系统进行有效的分离。

    也许有人会问,看看苹果。苹果的桌面系统Mac OS X和掌上系统iOS。它们不是有深度的类似吗!?

    对。但是深度类似不等于就是一个操作系统。苹果直到推出独立的iOS之后很久,才开始考虑两个操作系统之间的互相借鉴的问题。印象中第一代iPhone是2007年,而开始iOS和Mac OS的互相借鉴应该不早于2011年。

    而Windows 8的横空出世,试图整合桌面和移动操作系统,少了这3-4年的功夫。

    以微软的实力,基于Windows操作系统的核心,重新打造一个移动系统不算太困难的事情。这个系统有如下的特点:

    • 不需要桌面——和现在的Windows Phone界面相反,也和大家在Windows桌面系统中强烈要求有桌面相反,移动端系统可以没有“桌面”。
    • 常规的全屏独占式应用界面。

    好了。就这么多。

    应用?Windows桌面已经有那么多应用和应用开发者,转移到移动端,不是问题。何况我们还有Visual Studio。

    =========

    老罗在这个时候推出锤子,时机恰到好处。Smartisan OS基于Android,又不完全是Android。这在某种程度上,契合了政府禁止使用Windows 8的呼吁。当然,老罗做不到再推出一个桌面级别的操作系统,也没有特别的必要——比如政府可以考虑采用Ubuntu Kylin。

    信息安全的重要性怎么强调也不过分。我完全理解和支持政府在这个问题上的审慎和坚定。

    只是话要说回来,信息安全不等于信息封锁和过滤。我对GFW的存在深恶痛绝。

  • CSS2中文版下载地址

    这两天看我的访问记录,还有人在尝试下载我多年前翻译的CSS2规范的中文版。

    由于网站改版,原来的地址已经失效。

    现在可以直接从这个地址下载: http://www.rsywx.net/download/CSS2_Chinese_TR@SOE.zip

    免责声明:这个版本的翻译还是差不多7年前完成的,目前已经不再维护。目前也没有翻译CSS 3.x的计划。

  • SOLR之初体验——第一部分

    我准备用两部分来讲述SOLR的体验。第一部分,牵涉到后端,主要是SOLR的安装、启动、数据库配置;第二部分,牵涉到前端,主要是用Solarium提供的PHP接口在PHP中进行操作。

    本篇是第一部分。

    SOLR由Apache发行,是一个源自Apache Lucene的开源、企业级、搜索引擎项目。 在Sitepoint.com的这一系列文章详细讲述了SOLR和Solarium,有兴趣的读者可以自行浏览。

    安装、启动SOLR当前版本为4.8.0,以压缩包方式发布,有发行版现成使用和源代码供自行编译。下载地址:https://lucene.apache.org/solr/downloads.html

    SOLR发行包不大,压缩后仅150M左右。解压到某个目录后,安装就可以认为已经完成——当然还需要正确版本的Java支持,SOLR对Java的要求是在1.7以上。我的安装目录在:

    ~/temp/solr-4.8.0

    SOLR的发行版有一个内置的样本服务器配置,在example目录下,而其中又有一个样本数据库solr。 首先让我们启动这个数据库,看看有些什么东西。

    tr@hp:~/temp/solr-4.8.0/example$ java -jar start.jar

    这样就启动了SOLR服务,该服务缺省开放了8983端口的WEB管理界面,我们可以远程访问之:

    Ashampoo_Snap_2014.05.03_10h30m21s_011_Solr

    出现这个界面后,我们可以放心了:SOLR服务已经正常启动。SOLR确实是非常吃内存的服务,2G的内存空间被吃掉了1.75G。看来,要充分跑起SOLR,4G是最低配置了。

    在左侧“Core Selector”下拉框中选择一个我们要管理的核心——目前也只有一个,名叫“collection1”,于是就进入该核心的管理页面。在我看来,一个核心或者说这里的collection1,就相当于一张表格,用来保存我们需要进行索引和搜索的数据。此时界面变为对该核的管理界面:

    Ashampoo_Snap_2014.05.03_10h30m03s_010_SolrAdminMozillaFirefox_thumb.png

    左侧边栏有不少新的可选命令。我们会慢慢看。

    配置Schema和中文支持在上图中,可以看到SOLR这个实例的运行环境。对该实例,我们需要定制它的schema。SOLR使用XML文件来配置表格的结构,该文件名为schema.xml,位于example/solr/collection1/conf目录下。SOLR似乎只依赖这单一一个文件进行数据库的管理。每次SOLR启动的时候会对该文件进行扫描并进行后台的重建(比如增加/删除了字段,改变了字段的类型和属性等),但是并不会丢失数据 SOLR样本数据库中的schema.xml非常庞大,作为用户,有必要进行定制。

    另外一个对于全文搜索引擎而言,至关重要的是其对非英文内容的处理,对我来说,就是对中文的处理。所幸的是,SOLR对中文内容处理的非常好。

    schema.xml基本结构如下:

    • 首行,必然是标准的XML文件声明:<?xml version=1.0 encoding=UTF-8 ?>
    • 跳过很长的注释后,就进入schema声明:<schema name=resource version=1.5>name用来标记这个schema,而version是该schema定义时用到的语法的版本,目前就用1.5好了。
    • 字段定义。SOLR有几个保留的字段名,分别是_version_(用于schema的版本更新维护),_root_(在使用嵌套文档的时候要用),id(唯一标识符,建议保留)。
    • 字段定义由若干XML属性完成,常见的有:
      • name:字段名
      • type:字段类型
      • indexed:是否要加入索引
      • stored:是否存入数据库
      • required:是否必须
      • multiValued:是否允许有多个该字段的值。比如一个文档的tag通常是多个,因此这个字段的定义我一般会设置multiValued=true
    • 字段类型的元定义。这个用来定义上面定义的字段的类型。比如一个int是怎样的类型?这点很奇怪,因为在我看来,这些基本类型应该不用再定义的。但是既然SOLR有这个要求,我们也不妨遵循。
    • 这个元定义中需要特别提一提text_cjk这个类型。它就是对一个中文字段进行全文分词检索的关键。如果一个字段是中文内容,并且我们要对它进行全文检索,那么将这个字段设置为这个类型比较好。
  • 彼得初一(下)期中考试

    彼得初一(下)期中考试成绩如下:

    • 语文:76
    • 数学:98
    • 英语:97
    • 历史:46/50
    • 思品:40/50

    总分357,班级第9,估计能有年级前100左右(总共14*45约630人)。

    那天跑去开家长会,我问了班主任一个问题:他还有没有空间,还是已经比较稳定,就这个水平了?班主任几乎立刻用斩钉截铁的肯定语气对我说:肯定还有空间!就是不要太浮!浮就是不扎实,所以总是在一些很小的地方出错。

    比如这次数学扣两分,是因为一个最基本的配方在配一次项的时候忘记了乘以2(4X^2+???X+121),这里的???需要是2*11再乘以2,是44,而不是22。这种题目做了不知道有多少题,出错概率几乎为0,但就是因为还不够扎实,所以在最关键的时候小概率事件发生。

    再比如英语,作文扣了1分,完形填空扣了2分。作文1分应该也是因为没有完全看清要求中提供的材料和细节,在写的时候大意是不错了,但是可能还是漏了一个小点。完形填空有些难,考的是”mind+动名词”的语法点。

    动词+动名词(ing)形式他们已经学过,他也知道有几个动词是可以跟ing,也可以跟原型(比如stop),但是有可能含义不同;有几个是只能跟原型,有几个却只能跟ing。mind这个词儿有没有练到我不清楚,但是我相信在英语小报啊之类的地方有出现过。他当时可能蒙对了,但是没有仔细去研究、认真去记忆,所以到了考试就出了问题。

    家长会上,老师也讲到,初一年级已经早早的出现了两极分化。这个是老师们始料未及的。彼得也告诉我,他们班上已经有同学这次考试5门课都不及格,总分只有100多分的极端情况出现。

    我想这个和星海实验中学所谓的教学进度也是分不开的。家长会上,一位副校长明确表示,我们学校就是用5个学期结束6个学期的课,最后一个学期就是用来总复习的。

    在这样的情形下,我觉得初一下学期就出现初二才出现的两极分化其实就不奇怪了:课程本身难度就提高了,时间又压缩了,难免出现老师跳着讲,学生跳着记的场景。对于学习素质本身较差的学生来说,确实很艰难。

    ===我是分割线===

    初二要加入物理。我还不知道他物理会学的如何。我高中、大学、研究生这几年,物理反而是最差的。希望他能突破。

  • 任氏有无轩最新改版

    任氏有无轩改版已经很多次了,从最早的Symfony 1.x开始,在Symfony框架进入到2.x的时候重新改版了一次,最近的这次刚刚结束,也算是很大的一次。

    根据我在Bitbucket的提交记录,3月12日开始第一次重新提交,4月22日完成最后一次的提交,历时40余天。但是,众所周知,我的开发是很断续的,平均下来每天投入的时间不会超过1个小时,所以这次改版的总耗时不超过40小时,也就是常规工作时间下一周的工作量——加班的话也就3天左右。

    这次的改版牵涉面非常广。

    前端我还是使用Symfony 2来搭建我的应用,这个框架我已经用了很多年,如果没有什么大的变动和根本性的原因,我应该不会轻易切换别的框架——比如这个帖子里提到的Laraval和Phalcon。

    我原来的站点是用Bootstrap自己搭建的。优点是没有约束,自由度大,而且Bootstrap提供的部件已经给出了足够的基础来进行这个工作;缺点是我不是设计人员,设计出来的页面总是脱不了Bootstrap本身提供的一些模板。所以,下定决心花了$4在wrapbootstrap.com买了一个商业模板Grove(顺大便说一句,这个模板涨到$12了)。

    用商业模板的好处是,总可以找到适用的基本页面来改造;缺点是,很依赖它提供的样式。不过总的来说,利大于弊,我觉得我这个$4花得很值得。 另外,也许是我运气好,这个模板还提供了一个3D/2D幻灯片过渡的库,让我轻松做出很炫的Carousel场景切换效果。

    最后,我还加入了长久以来一直缺失的按照书籍tag搜索书籍的功能。下一步,我还想加入一个tag云。

    后端**后端是这次改动最大的地方。**

    首先,数据库结构重新编写。

    在我给Sitepoint写的文章中,我明确表示:我是很反对使用一个自增长的整数字段来作为主键(Primary Key)的。但是,为了进行Symfony 2下的数据自动填充和另外一个后台(还没有实现)Phreeze的要求,我不得不重新构造我的数据库为那些原来没有自增长字段PK的表格重新加入这样的一个主键。数据迁移工作也花费了不少重复性的工作。

    第二,部分前端的动态内容提供,我开始采用Dart,而不是之前的纯jQuery。使用Dart,我的开发速度大大加快。虽然有一些限制——比如我这个帖子中提到的,但是总体来说利大于弊,而且我作为曾经在苏州Google Developer Group组织的Fly Dart活动中主讲过Dart的人,当然那更应该以身作则,多使用一些Dart。

    第三,我整合了Wordpress的一些功能,比如获得最新的N个帖子。

    总的来说,这次的改造是非常成功的,部署也很顺利。感觉自己对Symfony 2的掌握又深入了一层。 放张首页的效果图(点击可看大图):

    Ashampoo_Snap_2014.04.23_19h33m20s_001_Chrome

  • 在Symfony 2中获取WordPress信息

    在我正在进行的任氏有无轩改版中,我希望在首页获得我的博客的一些信息,比如最新发布的五个帖子。

    我使用的博客后台是Wordpress,它提供了很好的编程接口,可以轻松地完成这个任务。而且Wordpress也提供了这些编程接口的说明。

    Wordpress对博客信息的操作是通过所谓的XML-RPC实现的,其官方文档见此处。它也提供了诸如MetaWeblog API接口和其它格式的API接口。经过比较后,我还是选择使用MetaWeblog API接口,主要是因为它调用相对更加简单,返回值虽然不完整,但是够用也很精练。

    获取最新的若干(缺省为4)篇帖子的代码如下:

    private function getRecentPostsFromWP($num=4)
        {
            require_once 'wordpress/wp-includes/class-IXR.php';
            $user='user';
            $pwd='password';
            $xmlclient='http://www.rsywx.net/wordpress/xmlrpc.php';
            $client=new IXR_Client($xmlclient);
            $params=array(0, $user, $pwd, $num);
            $client->query('metaWeblog.getRecentPosts', $params);
            $posts=$client->getResponse();
            return $posts;
        }

    这个函数以数组形式返回最新的几个帖子,在Twig中可以进一步使用诸如:

    {{rp.title}}
    {{rp.dateCreated.year}}年{{rp.dateCreated.month}}月{{rp.dateCreated.day}}日
    {{rp.description|striptags|truncate(120)}}

    等方式获取相关信息并展示。

    有兴趣的读者可以进一步参阅API说明,挖掘Wordpress更多的功能,并应用到自己的站点中。

  • Symfony 2中Twig模板的两个小技巧

    今天抓紧时间又更新了一下任氏有无轩的首页的改造。在我已经获得了我的博客的若干最新帖子的前提下,我需要在首页上显示其中的几个。 我要解决两个问题:

    1. 对帖子的内容进行过滤。
    2. 对过于长的帖子内容进行截断。

    由于Twig引擎在渲染HTML的内容时,缺省会将其作为<pre>文本输出,因此所有HTML/CSS效果都会丢失。这是可以接受的,但是问题在于,在这一过程中所有的HTML标记(如<p><img>等)也会按照转义输出,这样一来我们的输出中文字就会非常凌乱,不利于阅读。

    我要达到的是下面的效果:

    Ashampoo_Snap_2014.04.13_12h33m30s_002_MozillaFirefox.png

    也就是说,只输出文本,对于其中可能出现的HTML标记被剥离并不是太大的问题。 这可以通过如下的输出控制实现:

    rp.description|striptags

    接下来,要对这样输出的文字进行截断。Twig提供了一个truncate过滤器,但是要使用它需要进行一些设置。 修改app/config.yml并增加如下代码:

    services:
        twig.extension.text:
            class: Twig_Extensions_Extension_Text
            tags:
                - { name: twig.extension}

    然后对刚才输出的文字继续套用truncate

    rp.description|striptags|truncate(120)

    就可以得到图片中的效果了。

    本文收录于[go4pro.org]