by agate - Published: 2008-10-30 [7:58 上午] - Category: 历程

陈畅昨天好好把我给洗了一遍脑, 真是让我感到十分羞愧. 反思自己一直以来的生活关, 感觉实在是太天真, 太幼稚了! 睡觉起来, 开始回首昨晚的谈话, 总结一些记录下来, 我想这是对我最好的提醒和勉励!

一. 如果你在找工作, 请保证每天都有面试, 不是等着工作决定你的命运, 不是非某个公司不可. 你的态度决定了很多!
二. 你现在的工作不好不要抱怨, 是为了下一份更好的工作做积累!
三. 工作不比学习, 学习更多的考得是同学们的环境, 工作更靠你自己的把握! 主观能动性胜过客观环境.
四. 着眼于当下! 做好一件事情再去做其他的事情. 就比如看书吧! 看完一本是一本! 不要半途而废. 工作也是, 专注于一个领域, 放下躁动的心, 尽心做5年, 你已经是这个领域的强人了!
五. 上海是个好地方! 技术是最简单的工作! 等你有了历练才可能承受公务员这类的工作~
最后! 面包会有的! 房子会有的!

归纳就如下东西, 但是不知道为什么陈大哥说得我就如此的五体投地~ 很是感动!

Tags: [ ] - Comments: View Comments
by agate - Published: 2008-10-29 [3:39 下午] - Category: 程序编码

很早就在 "Web 开发大全 -- Ruby on Rails 版" 书中看到过 restful_authentication 这个鉴定插件了~ 但是一直都没使用过. 今天看到一个中文的 ROR 视频网站 -- rubycnrails.cn 上面用视频介绍了 restful_authentication 这个插件的使用(但是这位仁兄老是出错... 看着我好着急阿!) 呵呵! 于是我也试着使用了一番, 发现真的满好用的. 这里就记录一下, 顺便说一下需要注意的地方.

github 地址 http://github.com/technoweenie/restful-authentication/tree/master
(rubycnrails.cn 上面那个视频似乎是使用旧的版本... 大概不知道这个插件已经迁移到 github 上面了吧.)

安装:
$cd [your-rails-app]
$./script/plugin install git://github.com/technoweenie/restful-authentication.git

使用:
$./script/generate authenticated Model-Name [Controller-Name]
别忘了 rake 一下, 来建立你的数据库!

结果:
生成对应的 controller / model / view. 添加了对应的 routes: signup / login / logout. 当然, 还添加了

lib/authenticated_system.rb
lib/authenticated_test_helper.rb

这两个才是重要的插件功能! 其中 AuthenticatedSystem 中包含了诸如: logged_in?, current_kid 等重要方法! 到时候我们只需要在需要调用的 controller 中 include AuthenticatedSystem 就好了.

注意:
不要傻乎乎地学 README 中键入: ./script/generate authenticated user sessions 这个 s 最好不要!(不要说我违反了 RESTful 的理念, 我说的是最好不要!) 对于初学者来说先别加这个 s, 因为这个会带来很多配置上的模糊: 比如 routes.rb 中 resource 是定义为 'session', 但是设置具体命名路由的时候使用 controller 参数时又要设置为 'sessions'. 所以, 如果你对这里头的细节不是很清楚的话, 建议你改用单数作为这里控制器的名称:
$./script/generate authenticated user session 我建议这么写
当然! 你清除的话, 或者你不关心这个的话, 那还是写上那个 s 吧! 这样才够 RESTful!
其他很细致的内容还是看看源代码或者看看 Plugin 的 README 吧! 写得很不错!

by agate - Published: 2008-10-28 [9:04 上午] - Category: 程序编码

看看我的 rails 版本吧!
$ gem list rails

*** LOCAL GEMS ***
rails (2.1.2, 2.1.1, 2.1.0, 2.0.2, 1.2.6)

是不是很多呀? 用 rails 命令创建一个新应用的时候, 默认使用最新的版本进行构建. 很多情况下要创建特定版本的应用, 可以使用一个额外的参数来达到这个目的, 具体如下:
$rails _[version number]_ appname
例如, 我要建立一个基于 rails 1.2.6 版本的经典 depot 应用就可以:
$rails _1.2.6_ depot

Tags: [ ] - Comments: View Comments
by agate - Published: 2008-10-21 [7:34 上午] - Category: 开发环境

怎么说呢~ 我还是比较喜欢视窗系统下的使用开发方式(具体原因是 Linux 和 Mac 对中文字体的渲染实在是不敢恭维). 于是目前我使用开发 web 程序的方式是使用 VMware, 在视窗系统下使用 PuTTY 和视窗共享来操作 Linux 系统, 并进行开发. 效果挺不错的. 本文书写的原因是 autotest 在远程调用时候比较不容易实现可视化的自动测试(出错有声音啊, 有红字啊~). 所以经过变通思考我决定采用 Firefox + Greasemonkey 这样的搭配来实现定时访问 autotest 生成的 html 结果, 从而在视窗系统下对远端 Linux 开发机进行自动化测试和提示.

先看看效果图:

你会问, autotest 生成的 html 并不能自动刷新啊, 这里我就想到了 Greasemonkey 这个强大的 Firefox 自定义扩展插件. 可以通过自己手动书写 JS 来扩展页面功能/样式.

于是我便写了一个简单的 JS 脚本, 提供 n 秒自动刷新, 有 failures 就发出报告声. 脚本如下:

// ==UserScript==
// @name           rspec results auto refresh
// @namespace      agatezone
// ==/UserScript==

// modify vars
var time_left = 10;
var path = "file:///E:/my_help_files/GreasemonkeyFiles/rspec_results_auto_refre";

// script begin ---------
// init
init();

// play error sound while has errors.
if (hasError()) {
	var sound = document.createElement('div');
	document.getElementById('reload').appendChild(sound);
	sound.innerHTML = "<embed name=\"pmsound2player\" src=\"" + path + "player.swf\" flashvars=\"sFile=" + path + "failure.mp3\" menu=\"false\" allowscriptaccess=\"sameDomain\" swliveconnect=\"true\" type=\"application/x-shockwave-flash\" width=\"0\" height=\"0\">";
}

// start timer
reloadTimer();

/////////////////////////////

// functions start ++++++++++++++++
function init() {
	var summary = document.getElementById('summary');
	var p = document.createElement('p');
	var t = document.createTextNode('');
	p.setAttribute('id', 'reload');
	p.appendChild(t);
	summary.appendChild(p);
}

function setTitle(x) {
	document.title = x;
	document.getElementById('reload').firstChild.nodeValue = x + "...";
}

function reloadTimer() {
	if (time_left <= 0) {
		setTitle('Reloading...');
		window.location.reload();
	} else {
		setTitle ('Reload in ' + time_left + ' second' + (time_left == 1 ? '' : 's'));
		setTimeout (reloadTimer, 1000);
		time_left --;
	}
}

function hasError() {
	var result_text = document.getElementById('totals').firstChild.nodeValue;
	var re = /(\d+)\s+examples?,\s*(\d+)\s+failures?(,\s*(\d+)\s+pending)?/;
	var results = re.exec(result_text);
	if (results[2] != 0) {
		return true;
	} else {
		return false;
	}
}
// functions end ++++++++++++++++
// script end ---------

这里有两个文件 DOWNLOAD 主要作为错误提示音使用, 请解压开后放置到一个位置, 并且把这段代码里头的 path 修改为这两个文件存放的位置. 就比如我把这两个提示音文件放在:
c:\autotest_rspec\
下面, 那么 path 就改成:
file:///C:/autotest_rspec/
这样的网页地址形式.

这样便可以简单地在微软视窗操作系统下实现自动化测试远端开发机并给出结果提示.

灵感: Greasemonkey 太强大了! JavaScript 同样! Dom 模型更是了不起!

Tags: [ , , ] - Comments: View Comments
by agate - Published: 2008-10-17 [1:18 下午] - Category: 开发环境, 程序编码

羡不羡慕那些 rails 视频在 MAC OS X 下面帅气的自动跳出绿色和红色的自动测试提示呢? 当然如果你是 MAC 用户就不用羡慕了哈!(比如我就不羡慕嘿嘿) 但是大部分朋友都是 PC 呀! 没有 MAC 下的 Growl 作为 UI 提示工具怎么办呢? 没事啦! 这些我们都好解决, Ubuntu 下面我们可以用 rnotify 这个 ruby gnome 的消息提示工具. Windows 下我们可以用 ruby-snarl 这个消息提示工具啦! 当然还有 AutoIt 这类辅助工具! 这里我们先说 Ubuntu 这样的 GNOME 环境中的解决方案.

首先是安装 autotest, rspec, rspec_rails 三个插件
$sudo gem install autotest
$rails hello
$cd hello
$./script/plugin install http://rspec.rubyforge.org/svn/tags/CURRENT/rspec
$./script/plugin install http://rspec.rubyforge.org/svn/tags/CURRENT/rspec_on_rails
$./script/generate rspec

这样便安装好最基础的 BDD 环境了. 手动在你的 rails 目录下键入
$./script/autospec
这是这个自动测试不是在后台运行的, 因为他要显示信息嘛!
所以最小化这个终端窗口吧, 或者新开一个 Tab 来继续操纵你的 rails 应用.

就可以启动针对此 rails 应用的持续测试功能了. 让我们来试试看! 如何工作, 在终端中你的 rails 目录下键入:
$./script/generate rspec_scaffold post title:string
$rake db:migrate
$rake db:test:clone

看看你的那个自动测试窗口吧! (如果你的小机器不太快, 这个测试窗口还和原来一样, 那么稍等一会会, 他马上就运行咯!) 你大概会看到类似的结尾结果:

哈! 是不是很有成就感? (当时我满有的...) 呵呵, 但是这个只是在终端中看到的, 难不成要我们每次保存了新的东西都要光顾我们的终端信息么? Mac 下有 Growl 来做桌面 UI 气泡提示. 在 Ubuntu 这样的 GNOME 下我们可以使用 ruby-notify 来实现. 首先必须安装 ruby-gnome2 / libnotify-dev 和 ruby-libnotify 这些组件依赖. (其中 ruby-libnotify 需要手动安装)
$sudo apt-get install ruby-gnome2 libnotify-dev
以上安装好了 ruby-gnome2 和 libnotify-dev , 至于 ruby-libnotify 可以到其官方网站下载手动其源代码编译安装, 当前最新版本为 0.3.3, 在其下载页面我下好了 ruby-libnotify-0.3.3.tar.bz2 文件, 将其解压开好. 使用终端进入其目录中执行:
$ruby extconf.rb
$sudo make
$sudo make install

这样就安装好 ruby-libnotify 了! 其实就是用它来代替 Mac 下的 Growl 啦! 接着建立 ~/.autotest 文件并填入如下代码.

require 'rnotify'
require 'gtk2'

module Autotest::RNotify
  class Notification
    attr_accessor :verbose, :image_root, :tray_icon, :notification,
      :image_pass, :image_pending, :image_fail,
      :image_file_pass, :image_file_pending, :image_file_fail,
      :status_image_pass, :status_image_pending, :status_image_fail

    def initialize(timeout = 5000,
        image_root = "#{ENV['HOME']}/.autotest_images" ,
        verbose = false)
      self.verbose = verbose
      self.image_root = image_root
      self.image_file_pass = "#{image_root}/pass.png"
      self.image_file_pending = "#{image_root}/pending.png"
      self.image_file_fail = "#{image_root}/fail.png"

      raise("#{image_file_pass} not found") unless File.exists?(image_file_pass)
      raise("#{image_file_pending} not found") unless File.exists?(image_file_pending)
      raise("#{image_file_fail} not found") unless File.exists?(image_file_fail)

      puts 'Autotest Hook: loading Notify' if verbose
      Notify.init('Autotest') || raise('Failed to initialize Notify')

      puts 'Autotest Hook: initializing tray icon' if verbose
      self.tray_icon = Gtk::StatusIcon.new
      tray_icon.pixbuf = Gdk::Pixbuf.new(image_file_pending,22,22)
      tray_icon.tooltip = 'RSpec Autotest'

      puts 'Autotest Hook: Creating Notifier' if verbose
      self.notification = Notify::Notification.new('X', nil, nil, tray_icon)

      notification.timeout = timeout

      Thread.new { Gtk.main }
      sleep 1
      tray_icon.embedded? || raise('Failed to set up tray icon')
    end

    def notify(icon, tray, title, message)
      notification.update(title, message, nil)
      notification.pixbuf_icon = icon
      tray_icon.tooltip = "Last Result: #{message}"
      tray_icon.pixbuf = tray
      notification.show
    end

    def passed(title, message)
      self.image_pass ||= Gdk::Pixbuf.new(image_file_pass, 48, 48)
      self.status_image_pass ||= Gdk::Pixbuf.new(image_file_pass, 22, 22)
      notify(image_pass, status_image_pass, title, message)
    end

    def pending(title, message)
      self.image_pending ||= Gdk::Pixbuf.new(image_file_pending, 48, 48)
      self.status_image_pending ||= Gdk::Pixbuf.new(image_file_pending, 22, 22)
      notify(image_pending, status_image_pending, title, message)
    end

    def failed(title, message)
      self.image_fail ||= Gdk::Pixbuf.new(image_file_fail, 48, 48)
      self.status_image_fail ||= Gdk::Pixbuf.new(image_file_fail, 22, 22)
      notify(image_fail, status_image_fail, title, message)
    end

    def quit
      puts 'Autotest Hook: Shutting Down...' if verbose
      #Notify.uninit
      Gtk.main_quit
    end
  end

  Autotest.add_hook :initialize do |at|
    @notify = Notification.new
  end

  Autotest.add_hook :ran_command do |at|
    results = at.results.last

    unless results.nil?
      output = results[/(\d+)\s+examples?,\s*(\d+)\s+failures?(,\s*(\d+)\s+pending)?/]
      if output
        failures = $~[2].to_i
        pending = $~[4].to_i
      end

      if failures > 0
        @notify.failed("Tests Failed", output)
      elsif pending > 0
        @notify.pending("Tests Pending", output)
      else
        unless at.tainted
          @notify.passed("All Tests Passed", output)
        else
          @notify.passed("Tests Passed", output)
        end
      end
    end
  end

  Autotest.add_hook :quit do |at|
    @notify.quit
  end
end

然后呢, 这里有几个图片, 请你下载下来保存到 ~/.autotest_images 目录下(自己建立这个文件夹).

(注意哦! 文件名不要变哦! 分别为 pending.png pass.png fail.png)

打工告成! 你可以在 rails 工程目录里头执行:
$./script/autospec
不出意外的话你应该会看到如下结果

Tips:
1. ~/.autotest 这个文件可以定制 autotest 的运行.
2. ruby-libnotify 可以用于 GNOME 中作为消息提示.(注意哦! 用源代码编译安装哦!)

Tags: [ , , , , ] - Comments: View Comments
by agate - Published: 2008-10-17 [10:00 上午] - Category: 开发环境

我原先的环境:

RUBYGEMS VERSION: 1.2.0
RAILS VERSION: 2.1.1

但是当我升级到 RUBYGEMS 1.3.0 的时候, 每当用命令行生成一些 rails 文件的时候就会报:

Gem::SourceIndex#search support for Regexp patterns is deprecated 2.1.1

十分不爽! 于是寻寻觅觅问题所在, 在鸟语网站上查了很多都是说是 RUBYGEMS 1.3.0 的问题, 只是一个提醒罢了, 无关痛痒的! 但是我看着就是十分不爽呀! 就想能不能降级到 RUBYGEMS 1.2.0 呢? 在 google 上找到了一个方法!
$sudo gem install rubygems-update -v 1.2.0
问题是我原来是从 RUBYGEMS 1.2.0 升级上来的, 于是我的系统里存在 RUBYGEMS 1.2.0 和 1.3.0 两个升级文件, 默认情况下执行 update_rubygems 会升级到最新版本(这不是我们期望的). 于是必须使用 gem uninstall 来卸最新的 1.3.0 rubygems.
$sudo gem uninstall rubygems-update
会列出一个列表选择需要卸载的序号后回车即可!

这样卸载之后再次执行:
$sudo update_rubygems
就可以降级回到原先的 RUBYGEMS 1.2.0 咯! 等到 rails 或者 rubygems 自己解决这个不爽的提示之后我们在升级吧!

Tips:
gem env
gem list

Tags: [ , , ] - Comments: View Comments
by agate - Published: 2008-10-16 [8:22 下午] - Category: 程序编码

type in your terminal:

$sudo gem install ZenTest
$autotest

and the autotest has runned.

Tags: [ , , ] - Comments: View Comments
by agate - Published: 2008-10-16 [8:19 下午] - Category: 系统操作

这里说的 DNS 故障不是你自己电脑上 DNS 服务器设置的问题. 而是说我们笨笨的电信运营商们的 DNS 服务器出现了问题. 或者说被可爱的 GFW 浅封杀的域名们. 说这个解决方法的原因是: 我们的 github 登录不上了, 就算登录上了还是无法 clone 出版本. 解决方案十分简单, 就是在 hosts 文件中手动映射.

在 linux 下嘛就是 /etc/hosts 文件
加入:
65.74.177.129 github.com

其他不能登录的网站也是可以这么解决的(如果不是 gfw 封锁这个 ip 的就没问题). 但是如何找到这些对应的 ip 地址呢? 这里提供一个线查询 DNS 的网站: online nslookup(当然~ 用 google 查一下有很多类似网站).

Tags: [ , ] - Comments: View Comments
by agate - Published: 2008-10-12 [8:45 上午] - Category: 历程

据 xxx 统计, 如今全世界的程序员都有不同程度上的发福症状. 虽然每日不停加班, 甚至熬夜, 但是这个发福趋势不可抵挡! 这个 "野鸡" 统计也被我的诸多同学证实...

这里有一个减小肚子长大的最佳方案! 绝对可行, 只要你肯做, 不怕麻烦! 其实呢不累的, 就是吃饭过后的半个小时内不能坐下, 随便你干什么都必须保持你站着的状态! 我就靠这个把我的肚子减小了不少!

现在我要开始锻炼身体啦!!! 每天俯卧撑和仰卧起坐! 哑铃操... 每日坚持 45 分钟!!!

加油~~~~~~~~~~~~~~~

Tags: [ ] - Comments: View Comments
by agate - Published: 2008-10-11 [10:06 上午] - Category: 程序编码

http://chinaonrails.com/topic/view/2249.html 先是我发起了这个帖子, 问题和这篇文章一样... 纳闷的是为什么 rails 规定如此死板.

我想要建立一个名为 admin 的管理命名空间, 把所有的后台操作放置在这个命名空间下. 于是我就有一个想法, 把链接管理 -- LinksController 分解成一个文本链接和一个图片链接来方便细致管理. 但是还是想保留 LinksController 这个控制器. 于是我这么写 routes.rb 了:

map.namespace :admin do |admin|
	admin.resources :posts
	admin.resources :links
	admin.namespace :links do |link|
		link.resources :texts
		link.resources :images
	end
end

明显, 我想把 :links 即当作 resources 的资源, 又当作 namespace 这个空间的名字. 当时我想是完全行得通的! 我想可以有如下地址规则:

http://host:port/admin/links

http://host:port/admin/links/1

http://host:port/admin/links/texts

http://host:port/admin/links/texts/1

http://host:port/admin/links/images

http://host:port/admin/links/images/2

可是并非如此. 情况是这个 namespace 不认了. 当然前两条地址路由规则是没问题的, 问题是后面几个地址路由规则中 rails 会把 texts 和 images 当作 links 控制器的 action 方法, 情况大致就是这样的.

直到 ashchan 大哥提到他曾经在很老的 rails 版本中完成过 namespace 的嵌套, 我才回过头考虑我的配置和代码书写. 首先我重装了所有 gems 在一个隔离的 sandbox linux 虚拟机环境中, 并重新运行我的工程. 但是发现并不是 gems 的问题. 于是反思我的 routes.rb 代码. 得到如下解决方案:

map.namespace :admin do |admin|
	admin.resources :posts
	# 主要是下面这句 named routes[命名路由]
	admin.links "/links", :controller => "links"
	admin.namespace :links do |link|
		link.resources :texts
		link.resources :images
	end
end

这样即保证了 links 的控制器访问, 又保证了 links 命名空间下的 texts 和 images 控制器的访问.

从这件事情我发现 rails 真的不是我说的那么死板, 而是非常聪明灵活. 看看这个 admin.links 的命名路由吧! 过去我一直以为命名路由只能在 map 这个对象下使用, 现在看来, 其实这个 map 也只是代表着 / 这个根目录的一个命名空间对象罢了! 所以我们自定义的 namespace 的对象一样可以使用命名路由写法!

这里谢谢 ashchan 谢谢 rails!

Tags: [ ] - Comments: View Comments