保持习惯与坚持


(图:小时候的作业本)

在人生转瞬间过去1/3的时候,想想小时候的梦想,现在的追击,有多大的差距,人生的目标在不断的调整,不断的修正,追求的东西也发生了很大的变化。

小时候天真的想长大后,成为一个医生,再大一点,觉得当一个老师挺好的,高中的时候想以后搞物理吧,挺有意思,
上大学后,坚决放弃了自己的想法,后来成为了一名程序员,并一直做到了现在。
这段时间也转了不同的职业岗位,后端、数据统计、WAP、WEB、运维、前端、手机。一直在变幻着,有些变化是主动的有些是被动的接受了该有的变化,但整体上还是坚持了下来。

今天周五,准备写工作周报,习惯上打开ical看看本周的日程,看做了什么。突然想到这可能是我保持最长的习惯了
我一贯奉行长老们说的“好脑子不胜烂笔头” 所以些日程规划,这个习惯算是保持了下来。大概坚持了10年,
从什么时候开始的已经记不得清除了,虽然日记/日程的载体也几经变化,基本内容未变。

我们经常定一些计划,或长期或短期的,能真正坚持的又多少,能把计划变成习惯,真的很难,经常
为自己找各种理由来自我辩护,是因为xxx而不能xxx,下次注意之类的。自己终于把自己欺骗了,得了心里的
自我安慰,很快你制定的计划就会变成过去式,然后被你忘记。

想想那些好的习惯被你坚持下来了,那些早被你丢到了犄角旮旯。

(完)


按理说周五应该兴奋才是,不知道怎么的,今天特么伤感。

先写这么多,下班回家。

使用zsh替换bash shell


(图:zsh运行中)

昨天晚上看到在觅链上看到一篇文章,介绍了 zsh,对于我这么爱折腾软件的人,

肯定会尝试一下的。

zsh 是什么?

类 unix 系统默认的 shell 都是 bash,默认以/bin/sh 执行。

在 Mac OSX Terminal.app 下 bash 用这还可以,唯一让人不爽的是,多个目录来回的切换。

一级级的太麻烦了。

bash 的自动补全功能相对 zsh 就比较弱暴了,zsh 能进行命令参数补全,命令纠错,目录补全。

同时推荐z.sh,这个命令可以在多个目录里任意切换。

如输入 z wangxian.github 切换到我的博客目录 wangxian.github.io

还有一点是 zsh 的配置和主题,.oh-my-zsh 这个配置太给力了,默认已全部 OK。

安装与使用

其实 Mac osx 已经自带了 zsh,只是版本比较老,对于 zsh 使用没有影响。

不知道,别的系统自带了 zsh 了没有。

安装和详细功能介绍

gorun - Golang开发辅助工具


(图:Golang)

进行go开发不像PHP那样,刷新浏览器就行,需要你不停的CTRL-C来重载新的修改。
之前在做Nodejs开发的时候,有一个nodemon,可以自动重启。

所以就有了gorun这个小工具。

主要实现了2个功能

  1. 开发项目时,自动编译整个项目
  2. 直接运行一个文件,gorun my.go

项目地址

http://github.com/wangxian/gorun



开发过程中,参考了bee (beego的自动化工具,可惜只能为beego服务)

请放开你的F5


(图:F5 is important)

## 8月4日更新:  
1. 修改-dir参数为-rootdir
2. 新增了watchdir参数,如果rootdir下的目录很多,可以单独指定watchdir来缩小监控的目录。
3. 修改-port 为 -http,可以设置为 :4000 或监听特定的IP上,如: 192.168.1.118:4000
4. 修改-portproxy 为 -proxy ,可设置为 :80 或 www.baidu.com:80,开发本地程序。

在WEB开发中,我们干的最多的键盘操作是刷新你的浏览器,
在WIN平台下快捷键是F5,在OSX平台快捷键是COMMAND+R, 经常是修改代码,刷新浏览器,再修改代码
再刷新。

WebStorm可以可以LiveEdit,用了几次后,果断放弃了,还要安装浏览器插件,太不爽了。
最近在研究Golang,故尝试用golang开发一个小工具来解决这个问题。

现有的功能

Usage of orange:
-http=":4000": Static server port, The port must>1024, default :4000
-ignores="": Not watch files, split width `,` Not regexp eg: `.go,.git/`, default no ignores
-precmd="": Before refresh browser, execute precmd command. eg: `ls {0}`, {0} is the changed file
-proxy="": Proxy webserver when file saved refresh browser, like :80
-rootdir="./": Server root dir, default current dir
-watchdir="./": Watch dir which change will refresh the browser, default current dir

还有不少问题,正在努力解决中。
最严重的一个监控的目录个数不能太多,如果太多就会失败。

项目地址

https://github.com/wangxian/orange

被maruku给坑了



(图:maruku VS kramdown)

昨天在用jekyll写东西的时候, 遇到了一个非常诡异的事情,用到了markdown列表的格式,
嘿,解析一直不正常,提交到Github还是那样,后来Google了一下,发现可恶的 maruku 的问题。

maruku是Jekyll默认的Markdown解析模块,这个模块对中文支持很不好。
有人推荐用rdiscount果然问题得到解决。
后又发现一个比rdiscount更强大些的解析模块kramdown,支持更多的原生Markdown的扩展。

Usage:

1
sudo gem install kramdown

设置 _config.yml markdown: kramdown


最后:最喜欢kramdown的一点,行后加上2个空格或2个反斜线会被格式化成<br />
有点类似于”GitHub Flavored Markdown” (GFM) 所以为了你的人身安全,请远离maruku!

参考:
Quick Reference of kramdown

A go development tools - gorun

Golang 开发不像PHP开发那么方便,经常要进行CTRL+C,然后重新运行,
在搞nodejs开发的时候,经常用nodemon来自动重启nodejs app,
找了一下,没发现好用的go auto restart app工具。

遂计划开发一个这样的工具,这就是gorun
托管的项目地址:https://github.com/wangxian/gorun

Usage:

// 运行一个文件
gorun gofile.go

// 运行项目
cd your_project_dir;
gorun

Installation

go get -u github.com/wangxian/gorun

去旅行和去旅游的区别

看到了一个公众帐号上一篇文章,讲『旅行与旅游』的区别,觉得很有体会,分享给大家。
原文:https://app.yinxiang.com/shard/s5/sh/472a0360-7ad9-44f5-9f38-2e231ed47249/f91360389bfbc5f9ea6386e76bfbe49c

我也经常出去,走一走,在城市待时间长了,特别闷,出去散散心。

去的地方有远有进,坐火车,坐汽车,做飞机,不管怎么去,说好听点是旅游,
实际上出去旅行真实一个劳苦的事儿,坐车,换乘,预订酒店,出行线路,天气,吃,都得考虑,
如果遇到不顺心的事儿,更纠结,好好的心情,突然被打乱了,别了一肚子气,这是出去散心呢,还是
自己给你自己找气受呢?

我的观点,旅行和旅游2个词,『旅行』更具有文艺范,旅游觉得是一个消费的名词,为了去一个
地方而去一个地方,旅行更显孤单,自由。旅游中那么烦心的事情,降低了旅行的乐趣。

去旅游不可能都顺风顺水,遇到事情,冷静,淡定的对待,别给自己过不去,即使被宰了,
也不要怒气冲冲,怨天尤人,平常心,以不变应万变。

人生就是一种旅行!

Golang package manage VS NPM

研究Go语言有段时间了(也叫Golang)现代的开发语言都有一个包管理,go也自带了一个包管理没有名字叫go get
Nodejs的包管理叫npm,go get虽然简单直接,但和Node.js npm 一比还是比较弱的,粗略的讲有3个方面。

  • 命令行使用上的差别
  • 版本管理
  • 仓库源

命令行使用上的差别

先说命令行使用,go get 命令,我已知有用的只有一个参数 -u 更新已安装的包。没有删除已安装的包命令,
不能查看第三方包的介绍,不能搜索你想要的包功能,等等,和npm一比简直是弱爆了。

npm的功能

Usage: npm <command>

where <command> is one of:
    add-user, adduser, apihelp, author, bin, bugs, c, cache,
    completion, config, ddp, dedupe, deprecate, docs, edit,
    explore, faq, find, find-dupes, get, help, help-search,
    home, i, info, init, install, isntall, issues, la, link,
    list, ll, ln, login, ls, outdated, owner, pack, prefix,
    prune, publish, r, rb, rebuild, remove, repo, restart, rm,
    root, run-script, s, se, search, set, show, shrinkwrap,
    star, stars, start, stop, submodule, tag, test, tst, un,
    uninstall, unlink, unpublish, unstar, up, update, version,
    view, whoami

版本管理

go的包,没有版号,当然goget也就没有了版本管理的功能,
对于npm每一个包,都有一个package.json文件描述该包,什么版本,该包依赖于那些包,
当你npm install的时候npm会把依赖的包安装上,更强大的是,包可以指定依赖包的版本。

如果包的依赖包没有版本,就需要使用者自己确认,如果依赖包升级后,可以导致包不能使用。

对于这些功能,goget,一个都冇,比起来,go还是很年轻。

仓库源

npm有一个官方的仓库https://npmjs.org/ , goget没有,goget在线安装只能支持
有限的几个源 google code, github等。

没有官方源,也就不能统一管理,对包进行审核等,虽然现在npm也没有审核,但可以看到那些包是被使用和
下载最多的,这样大家认为好的,基本上可以确定是优质的包。

没有官方源只能靠你的一双慧眼了。

总结

路漫漫其修远兮,吾将上下而求索。

实战AngularJS开发

过年的时候,研究过Angular.js 这个还算大名鼎鼎的js库,还写了一篇blog, \
『[学习笔记]Angular.js学习笔记与感悟』

但没动手试过,怎么来开发一个todo的小应用。

开发angular.js应用,不用你从零开始,要么说大公司维护的框架不一样呢(Supper Google),angularjs的文档就不说了,
详细的开发文档,看的都让你觉得头疼,入门有一个AngularJS Totour「angularjs-phonecat」,
然后有一个开发说明 Developer Guide,最后还有一个 Api Reference,把这些玩意儿看完,都需要好长时间。

OK,现在来动手来开发一个angularjs todo App, angularjs 提供了一个seed, 你可以从这个seed开始。

Angularjs seed on Github. https://github.com/angular/angular-seed

把seed中包含:LICENSE README.md app/ config/ index.html logs/ scripts/ test/
app目录里是app的主程序,script有nodejs的webserver方便开发,原因是因为angularjs views,你懂的。

app/目录里有2个html, index.html, index-async.html(异步加载js)

index.html

<!doctype html>
<html lang="zh_CN" id="ng-app" ng-app="myApp">
<head>
  <meta charset="utf-8">
  <title>My Todo</title>
  <link rel="stylesheet" href="css/reset.css"/>
  <link rel="stylesheet" href="css/app.css"/>
</head>
<body>
<div class="page">
  <div class="header box">
    <a href="index.html"><h1>My Todo</h1></a>
  </div>

  <div class="main box" ng-view>

  </div>

  <div class="foot">
    Copyright &copy; <a href="http://wangxian.me">wangxian.me</a> 木頭 <br />
    一个简易的 todo 程序(方案: Github+AngularJS+JSON3)
    directive V<em app-version></em>, value: {{ 'Current version is v%VERSION%' | interpolate }}
  </div>

</div>

<!--[if lt IE 8]>
<script type="text/javascript" src="http://bestiejs.github.io/json3/lib/json3.min.js"></script>
<![endif]-->

<!-- In production use:
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
-->

<script src="lib/angular/angular.js"></script>
<script src="js/app.js"></script>
<script src="js/services.js"></script>
<script src="js/controllers.js"></script>
<script src="js/filters.js"></script>
<script src="js/directives.js"></script>

</body>
</html>

首页是一个layout,和加载资源的作用。

列表视图:partials/list.html

<div class="box post">
  <p><input type="text" placeholder="Create a new Todo." name="title" class="submit" ng-enter="newTodo($event)"></p>
</div>

<div class="box todos">
  <h2 class="box">待办事项</h2>
  <ul>
    <li class="item" ng-repeat="x in list | orderBy:'date':true">
      <span ng-class="itemClass(x.finished)">{{x.title}}</span>
      <span class="date">({{x.date | date:'yyyy-MM-dd HH:mm:ss'}})</span>
      <a href="" ng-click="gotoEdit(x)">编辑</a>
      <a href="" ng-show="! x.finished" ng-click="itemFinished(x)">完成</a>
      <a href="" ng-show="x.finished" ng-click="itemRenew(x)">恢复</a>
      <a href="" ng-click="itemDelete(x)">删除</a>
    </li>
  </ul>
</div>

编辑视图:partials/edit.html

<div class="box post">
  <h2>编辑</h2>
  <p><input type="text" class="submit" ng-enter="itemUpdate($event)" ng-model="title" value="{{title}}"></p>
  <p>回车提交</p>
</div>

app/js/app.js

// Declare app level module which depends on filters, and services
angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'myApp.controllers']).
  config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
    $routeProvider.when('/list', {templateUrl: 'partials/list.html', controller: 'ListCtrl'});
    $routeProvider.when('/edit/:id', {templateUrl: 'partials/edit.html', controller: 'EditCtrl'});
    $routeProvider.otherwise({redirectTo: '/list'});

    $locationProvider.html5Mode(false).hashPrefix("!");
  }]);

定义Angularjs路由,使用了$locationProvider, 关闭了html5的URL,启用hashbang的方式的URL。
首页url,./index.html#!/list, 编辑URL,./index.html#!/edit/120, 如果不满足
上面的2个URL,则跳转到 ./index.html#!/list

并且指定list对应的控制器,ListCtrl, 编辑页的控制器 EditCtrl

app/js/controllers.js

// 把todo信息存储在变量中
var list = [
  {
    "id"      : 1,
    "title"   : "安装mongoskin模块,npm install mongoskin",
    "date"    : 1286461782373,
    "finished": 0
  },
  {
    "id"      : 2,
    "title"   : "测试本地条已完成!",
    "date"    : 1276461782373,
    "finished": 1
  }
];

angular.module('myApp.controllers', []).
  controller('ListCtrl', ['$scope', '$location', "opt", "alert", function($scope, $location, opt, alert) {

    $scope.list = list

    // 每条记录的class
    $scope.itemClass = function (finished) {
      // console.log("new:", finished)
      return finished ? "del" : "new"
    }

    // 点击完成,设置为已完成,会自动更新view,为已完成。
    $scope.itemFinished = function (item) {
      // console.log(item)
      item.finished = 1
    }

    // 重新设置为 未完成
    $scope.itemRenew = function(item) {
      item.finished = 0;
    }

    // 删除item
    $scope.itemDelete = function(item) {
      for(var i=0, len=$scope.list.length;i<len;i++) {
        if(item === $scope.list[i]) {
          $scope.list.splice(i, 1);
        }
      }
    }

    // 添加todo
    $scope.newTodo = function(e) {
      var data = {}
      data.id = this.list.length+1;
      data.title = e.target.value;
      data.finished = 0
      data.date = (new Date()).getTime()

      this.list.push(data)
    }

    // 编辑todo item
    $scope.gotoEdit = function(item){
      $location.url("/edit/"+ item.id)
    }
  }])


  .controller('EditCtrl', ['$scope', '$routeParams', '$location', function($scope, $routeParams, $location) {
    // console.log($routeParams)
    // console.log(list)
    var _data = list[ $routeParams.id - 1 ];
    $scope.title = _data.title;

    // 当在编辑框中,回车提交后,更新todo, 并回到首页
    $scope.itemUpdate = function(e) {
      _data.title = $scope.title;
      $location.url("/list")
    }

  }]);

上面是angularjs-todo的关键代码,实现一个简单的应用,用angularjs,非常方便,angularjs为一个独立的库
并且自带jqLite, 简易的jquery,基本上不用依赖第三方库,关于模板,可以看到angularjs本身就模板,典型的
DOM 模板型。

Angularjs最关键的技术就数依赖注入了,DI系统,DI系统帮你做了很多事情。

用angularjs和别的库,最不一样的地方,在写HTML的时候,模板就出来了,要注意HTML和控制器的交互。
按照angularjs的思想去做页面。

如果遇到复杂的逻辑,可以封装成services,由于上面的例子比简单,所以就没把todo存储操作进行封装,放到了内存中。

/* Services Example */
angular.module('myModule', []).
 value('a', 123).
 factory('a', function() { return 123; }).
 directive('directiveName', ...).
 filter('filterName', ...);

Angularjs的services主要是有以上几种。

所以用angularjs开发单页应用,非常简单,文档什么都比较全。
只是现在国内用的不多,国内用的最多的还是backbone.js

还有Angularjs默认支持IE8+, 不过很容易解决,Develop Guide上提供了解决办法

上面的angularjs-todo 已经放到了Github上。\
地址:https://github.com/wangxian/angularjs-todo\
在线演示:http://wangxian.me/angularjs-todo

读「新安魂曲」有感


王晋康是我喜欢的科幻小说作家,最近读了他的中篇小说《新安魂曲》,觉得很有意思,与大家分享一下感受。

整个故事比较简单,讲20xx年,人类启动了『环宇旅行』为了验证我们所在宇宙,是否是一个『超圆体』假说。
『夸父号』飞船启航了,船上载了3个乘客,一男一女两个小孩,还有一个老头(环宇旅行的发起者),如果我们的宇宙真的是一个超圆体的话
经过若干年后,夸父号将能再次回到地球。

飞船经过若干次的加速,达到了0.99光速,根据相对论,这时候时间对飞船上的人来说已经没有意义,
可能眨眼间就过去了千万年,后来老头去世了,经过了若干年的旅行后,飞船外的时间,已经过去了N多年,
又经过了若干年,宇宙热寂了,宇宙之光灭了。

小说的结局,经过若干年后由于环宇计划的实施,鼓励了对宇宙的探索,最终人类使地球也变成光速,从而逃过了
太阳的熄灭。人类得以生存,最后第一代夸父号光荣回归。最后还留了一个小悬念,关于未来人的外形。

不得不感康,这篇小说的尺度自大。也留下了不少的思考,一,时间意义是什么? 二,我们将往那里去。三,宇宙的边界
四,宇宙的边界外是什么? 五、宇宙有界无限是怎么个感受,如果你是上帝的视角的话。

当飞船内外瞬间千万年来说,时间还有什么意义。未来人来是什么样的,什么样的形态,进化到什么程度,
我们曾经追求的东西意义,我们的执着的意义。

科幻小说最后,都能归结到哲学的三个经典问题上来,你懂的。