<?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>haojii</title>
	<atom:link href="http://www.haojii.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.haojii.com</link>
	<description>一个专注于技术的IT男</description>
	<lastBuildDate>Thu, 19 Apr 2012 07:58:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>git stash</title>
		<link>http://www.haojii.com/2012/04/git-stash/</link>
		<comments>http://www.haojii.com/2012/04/git-stash/#comments</comments>
		<pubDate>Thu, 19 Apr 2012 07:58:49 +0000</pubDate>
		<dc:creator>Jacky</dc:creator>
				<category><![CDATA[杂项]]></category>
		<category><![CDATA[git]]></category>

		<guid isPermaLink="false">http://www.haojii.com/?p=660</guid>
		<description><![CDATA[My git stash commands usage order: git stash [save [--patch] [-k&#124;--[no-]keep-index] [-q&#124;--quiet] [&#60;message&#62;]] git stash ( pop &#124; apply ) [--index] [-q&#124;--quiet] [&#60;stash&#62;] git stash list [&#60;options&#62;] git stash clear git stash show [&#60;stash&#62;] git stash drop [-q&#124;--quiet] [&#60;stash&#62;] git &#8230; <a href="http://www.haojii.com/2012/04/git-stash/">继续阅读 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>My git stash commands usage order:</p>
<pre>git stash [save [--patch] [-k|--[no-]keep-index] [-q|--quiet] [&lt;message&gt;]]
git stash ( pop | apply ) [--index] [-q|--quiet] [&lt;stash&gt;]
git stash list [&lt;options&gt;]
git stash clear
git stash show [&lt;stash&gt;]
git stash drop [-q|--quiet] [&lt;stash&gt;]
git stash branch &lt;branchname&gt; [&lt;stash&gt;]</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.haojii.com/2012/04/git-stash/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OSGi, Felix, Maven, Pax Plugin, Eclipse</title>
		<link>http://www.haojii.com/2012/02/osgi-felix-maven-pax-plugin-eclipse/</link>
		<comments>http://www.haojii.com/2012/02/osgi-felix-maven-pax-plugin-eclipse/#comments</comments>
		<pubDate>Thu, 23 Feb 2012 10:08:17 +0000</pubDate>
		<dc:creator>Jacky</dc:creator>
				<category><![CDATA[JavaEE]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Felix]]></category>
		<category><![CDATA[Maven]]></category>
		<category><![CDATA[OSGI]]></category>
		<category><![CDATA[Pax Plugin]]></category>

		<guid isPermaLink="false">http://www.haojii.com/?p=653</guid>
		<description><![CDATA[7.0 采用了osgi作为基础架构，平台已经差不多搭建完毕，项目正在开发上面的服务，因为之前没有参加基础架构搭建的工作，所以从头开始研究一下OSGi，然后发现开发环境不太理想，具体来说，maven-pax-plugin包装好的osgi环境还算方便，就是和eclipse的集成还不行。 准备说一说我是如何把开发环境理顺的。 首先是Maven Pax Plugin，如他项目主页介绍的，这款插件是OSGi的瑞士军刀，提供了创建，构建，管理，部署多种类型的OSGi bundle。它提供了一些脚本可供调用，也可以在maven命令行直接使用，这个比较赞。默认使用的是Felix的OSGi实现。 然后学习OSGi最好是找篇教程，Felix提供的这个教程貌似不错，我就准备照这个走一遍看看。 第一个例子是ServiceEventListener，例子不错但是教程本身没说如何创建此工程，我参考了maven-pax-plugin的usage页，用到两个命令mvn org.ops4j:maven-pax-plugin:create-project和mvn pax:create-bundle，然后用mvn eclipse:eclipse创建eclipse工程文件。 命令如下： 然后我就把这两个工程simple-api和simple-impl导入到了eclipse，首先发现两个问题 1. 这两个工程都不是Maven工程，而且项目依赖不正确 2. 这两个项目的pom文件都是红的，提示compile和testCompile相关的错 那我是怎么手工修这两个问题的呢？ 1. right click project -&#62; config -&#62; Convert to maven project 首先将这两个工程转换成Mavn工程 然后，打开.classpath文件，将两个osgiR4的jar包依赖替换成这个 2. 打开pom文件，用提示的quickFix修改掉这两个编译的问题，这时候pom文件里会多出这么一段 3. 这时候还需要right click project -&#62; Maven &#8230; <a href="http://www.haojii.com/2012/02/osgi-felix-maven-pax-plugin-eclipse/">继续阅读 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>7.0 采用了osgi作为基础架构，平台已经差不多搭建完毕，项目正在开发上面的服务，因为之前没有参加基础架构搭建的工作，所以从头开始研究一下OSGi，然后发现开发环境不太理想，具体来说，maven-pax-plugin包装好的osgi环境还算方便，就是和eclipse的集成还不行。</p>
<h1>准备说一说我是如何把开发环境理顺的。</h1>
<p>首先是<a href="http://www.ops4j.org/projects/pax/construct/maven-pax-plugin/index.html" target="_blank">Maven Pax Plugin</a>，如他项目主页介绍的，这款插件是OSGi的瑞士军刀，提供了创建，构建，管理，部署多种类型的OSGi bundle。它提供了一些脚本可供调用，也可以在maven命令行直接使用，这个比较赞。默认使用的是Felix的OSGi实现。</p>
<p>然后学习OSGi最好是找篇教程，<a href="http://felix.apache.org/site/apache-felix-osgi-tutorial.html" target="_blank">Felix提供的这个教程</a>貌似不错，我就准备照这个走一遍看看。</p>
<p>第一个例子是ServiceEventListener，例子不错但是教程本身没说如何创建此工程，我参考了<a href="http://www.ops4j.org/projects/pax/construct/maven-pax-plugin/usage.html" target="_blank">maven-pax-plugin的usage页</a>，用到两个命令mvn org.ops4j:maven-pax-plugin:create-project和mvn pax:create-bundle，然后用mvn eclipse:eclipse创建eclipse工程文件。</p>
<p>命令如下：</p>
<p>&gt;mvn org.ops4j:maven-pax-plugin:create-project &quot;-DgroupId=my.example&quot; &quot;-DartifactId=project&quot;<br />
&gt;cd project<br />
&gt;mvn pax:create-bundle &quot;-DbundleName=simple-api&quot; &quot;-Dpackage=org.example.simple&quot; &quot;-Dinternals=false&quot;<br />
&gt;mvn pax:create-bundle &quot;-DbundleName=simple-impl&quot; &quot;-Dpackage=org.example.simple&quot; &quot;-Dinterface=false&quot;<br />
&gt;cd simple-api<br />
&gt;mvn eclipse:eclipse<br />
&gt;cd ../simple-impl<br />
&gt;mvn eclipse:eclipse</p>
<h2>然后我就把这两个工程simple-api和simple-impl导入到了eclipse，首先发现两个问题</h2>
<p>1. 这两个工程都不是Maven工程，而且项目依赖不正确<br />
2. 这两个项目的pom文件都是红的，提示compile和testCompile相关的错</p>
<h2>那我是怎么手工修这两个问题的呢？</h2>
<p>1. right click project -&gt; config -&gt; Convert to maven project<br />
首先将这两个工程转换成Mavn工程<br />
然后，打开.classpath文件，将两个osgiR4的jar包依赖替换成这个</p>
<pre class="brush: xml; title: ; notranslate">&lt;classpathentry kind=&quot;con&quot; path=&quot;org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER&quot;/&gt;;
</pre>
<p>2. 打开pom文件，用提示的quickFix修改掉这两个编译的问题，这时候pom文件里会多出这么一段</p>
<pre class="brush: xml; title: ; notranslate">
&lt;!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.--&gt;
  			&lt;plugin&gt;
  				&lt;groupId&gt;org.eclipse.m2e&lt;/groupId&gt;
  				&lt;artifactId&gt;lifecycle-mapping&lt;/artifactId&gt;
  				&lt;version&gt;1.0.0&lt;/version&gt;
  				&lt;configuration&gt;
  					&lt;lifecycleMappingMetadata&gt;
  						&lt;pluginExecutions&gt;
  							&lt;pluginExecution&gt;
  								&lt;pluginExecutionFilter&gt;
  									&lt;groupId&gt;org.ops4j&lt;/groupId&gt;
  									&lt;artifactId&gt;
  										maven-pax-plugin
  									&lt;/artifactId&gt;
  									&lt;versionRange&gt;
  										[1.5,)
  									&lt;/versionRange&gt;
  									&lt;goals&gt;
  										&lt;goal&gt;testCompile&lt;/goal&gt;
  										&lt;goal&gt;compile&lt;/goal&gt;
  									&lt;/goals&gt;
  								&lt;/pluginExecutionFilter&gt;
  								&lt;action&gt;
  									&lt;ignore&gt;&lt;/ignore&gt;
  								&lt;/action&gt;
  							&lt;/pluginExecution&gt;
  						&lt;/pluginExecutions&gt;
  					&lt;/lifecycleMappingMetadata&gt;
  				&lt;/configuration&gt;
  			&lt;/plugin&gt;
</pre>
<p>3. 这时候还需要right click project -&gt; Maven -&gt; update project configuration</p>
<p>这时候，环境问题基本就OK了，照着例子敲好代码，然后mvn clean install pax:provision就OK了</p>
<p>g! lb<br />
START LEVEL 6<br />
ID|State |Level|Name<br />
0|Active | 0|System Bundle (4.0.2)<br />
1|Active | 5|my.example.project.simple-api [org.example.simple] (1.0.1.SNAPSHOT)<br />
2|Active | 5|my.example.project.simple-impl [org.example.simple] (1.0.1.SNAPSHOT)<br />
3|Active | 1|Apache Felix Gogo Command (0.12.0)<br />
4|Active | 1|Apache Felix Gogo Runtime (0.10.0)<br />
5|Active | 1|Apache Felix Gogo Shell (0.10.0)</p>
<p>Note: 另外编译的时候发现版本问题，在顶级pom里加上这么一段解决了，还不知道本质原因</p>
<pre class="brush: xml; title: ; notranslate">
&lt;plugin&gt;&lt;!-- Compile --&gt;
		        &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
		        &lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
		        &lt;configuration&gt;
		          &lt;source&gt;1.6&lt;/source&gt;
		          &lt;target&gt;1.6&lt;/target&gt;
		        &lt;/configuration&gt;
		        &lt;executions&gt;
		          &lt;execution&gt;
		            &lt;id&gt;compile-for-this-application&lt;/id&gt;
		            &lt;goals&gt;
		              &lt;goal&gt;compile&lt;/goal&gt;
		            &lt;/goals&gt;
		          &lt;/execution&gt;
		        &lt;/executions&gt;
	      &lt;/plugin&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.haojii.com/2012/02/osgi-felix-maven-pax-plugin-eclipse/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>新浪微博oauth2</title>
		<link>http://www.haojii.com/2011/12/omniauth-weibo-oauth2/</link>
		<comments>http://www.haojii.com/2011/12/omniauth-weibo-oauth2/#comments</comments>
		<pubDate>Wed, 28 Dec 2011 14:09:42 +0000</pubDate>
		<dc:creator>Jacky</dc:creator>
				<category><![CDATA[Ruby On Rails]]></category>
		<category><![CDATA[oauth]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.haojii.com/?p=648</guid>
		<description><![CDATA[前两天基于gem omniauth 1.0，实现了新浪微博oauth2的strategy，项目主页 https://github.com/jihao/omniauth-weibo 测试过程中发现新浪微博开放平台oauth2的两个问题 1. access_token response 不够标准，它返回的 “content-type”=&#62;”text/plain;charset=UTF-8&#8243;, 其实返回值是json格式，如果http头返回”application/json” 就更好了，省得开发人员手工处理。 2. OAuth授权后获得access_token，后续验证用户信息调用account/get_uid，微博API要求请求参数里必须填写access_token，这里比较难说是谁的问题，但是比较来说github instagram和oauth2 gem的默认行为都兼容，唯独新浪微博需要手工设置query参数，对程序员的易用性兼顾不够。]]></description>
			<content:encoded><![CDATA[<p>前两天基于gem omniauth 1.0，实现了新浪微博oauth2的strategy，项目主页 <a href="https://github.com/jihao/omniauth-weibo">https://github.com/jihao/omniauth-weibo</a></p>
<p>测试过程中发现新浪微博开放平台oauth2的两个问题<br />
1. access_token response 不够标准，它返回的 “content-type”=&gt;”text/plain;charset=UTF-8&#8243;, 其实返回值是json格式，如果http头返回”application/json” 就更好了，省得开发人员手工处理。</p>
<p>2. OAuth授权后获得access_token，后续验证用户信息调用account/get_uid，微博API要求请求参数里必须填写access_token，这里比较难说是谁的问题，但是比较来说github instagram和oauth2 gem的默认行为都兼容，唯独新浪微博需要手工设置query参数，对程序员的易用性兼顾不够。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.haojii.com/2011/12/omniauth-weibo-oauth2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>FaceTime升级Mac Lion之后不能登陆的解决办法</title>
		<link>http://www.haojii.com/2011/10/facetime-can-not-login-after-upgrade-to-mac-lion/</link>
		<comments>http://www.haojii.com/2011/10/facetime-can-not-login-after-upgrade-to-mac-lion/#comments</comments>
		<pubDate>Thu, 20 Oct 2011 15:44:39 +0000</pubDate>
		<dc:creator>Jacky</dc:creator>
				<category><![CDATA[小问题]]></category>
		<category><![CDATA[FaceTime]]></category>
		<category><![CDATA[Mac]]></category>

		<guid isPermaLink="false">http://www.haojii.com/?p=645</guid>
		<description><![CDATA[Meet the same problem like me that FaceTime can&#8217;t login after upgrade to MacOS Lion? My solution &#38; it worked:]]></description>
			<content:encoded><![CDATA[<p>Meet the same problem like me that FaceTime can&#8217;t login after upgrade to MacOS Lion?</p>
<p>My solution &amp; it worked:</p>
<pre class="brush: bash; title: ; notranslate">
sudo mv /Applications/FaceTime.app ~/Downloads/
sudo mv ~/Downloads/FaceTime.app /Applications/
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.haojii.com/2011/10/facetime-can-not-login-after-upgrade-to-mac-lion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>rails-oauth-连接新浪微薄记录</title>
		<link>http://www.haojii.com/2011/09/rails-oauth-with-sina-weibo-tutorial/</link>
		<comments>http://www.haojii.com/2011/09/rails-oauth-with-sina-weibo-tutorial/#comments</comments>
		<pubDate>Sun, 04 Sep 2011 13:53:02 +0000</pubDate>
		<dc:creator>Jacky</dc:creator>
				<category><![CDATA[Ruby On Rails]]></category>
		<category><![CDATA[devise]]></category>
		<category><![CDATA[oauth]]></category>
		<category><![CDATA[omniauth]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[新浪微薄]]></category>

		<guid isPermaLink="false">http://www.haojii.com/?p=637</guid>
		<description><![CDATA[这是一个简单的rails程序，技术上主要是devise,omniauth这个两个gem的使用 功能一个注册登陆系统，登陆完成之后，点击新浪图标，oauth连接/授权/关联新浪微薄账号，取得用户的相关微薄数据，上一张完成之后的页面截图就清楚些了。 步骤如下 使用devise实现注册登陆功能 使用omniauth实现新浪微薄的oauth认证 配置omniauth 完成新浪微薄oauth，保存access_token, access_token_secret到数据库 使用之前存下来的access_token, access_token_secret调用新浪API取所需要的数据 OK，下面是从创建这个rails app开始的完整步骤 首先是1.使用devise实现注册登陆功能 devise真的很好用，这步骤做完之后，基本的注册登陆功能已经完备，可以访问http://localhost:3000 验证一下 接下来2.使用omniauth实现新浪微薄的oauth认证 A. 配置omniauth B. 完成新浪微薄oauth，保存access_token, access_token_secret到数据库 使用omniauth是如此简单，你只需要加上这个link（/auth/:provider）就行了，这里的provider是tsina OK，用户登陆完就能看到这个链接了，点一下试试看，首先是一个授权app的页面，这时候输入新浪微博的用户密码，确认授权，然后不出意外你看到的是这个效果 我们再来回顾一下oAuth的流程，这个是新浪提供的一个流程图，我们正处于重定向到Callback_url这个阶段，而我们应用还没有定义回调的url OK，下一步就是定义我们的callback_url 先看看oAuth成功没有，code可以简单点 再次点击新浪图标，我们能看到一堆文本信息，包括token，secret等等，说明oAuth已经成功了。 C. 使用之前存下来的access_token, access_token_secret调用新浪API取所需要的数据 现在我们需要的数据都能取到了，然后思考一个问题，貌似我们应该把这个授权信息存下来，然后就不需要每次用户都授权一下才能取API数据。 建立下面这个authorization model存授权信息 OK,回到回调方法里，我们要把有用的数据存到model里进而持久化 然后我们希望每次用户刷新首页的时候，我们去取一下他授权微薄的最新信息（home#index是我们的root_url还记得不） &#160; 按照这个步骤，就能成功看到最终成果了。 Notes:上文所用的环境如下,完整代码可以在这找到https://github.com/jihao/rails_apps_for_fun/tree/master/authentication 这个过程中找到的较好的参考文档/资源 https://github.com/plataformatec/devise &#8230; <a href="http://www.haojii.com/2011/09/rails-oauth-with-sina-weibo-tutorial/">继续阅读 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>这是一个简单的rails程序，技术上主要是devise,omniauth这个两个gem的使用</p>
<p>功能一个注册登陆系统，登陆完成之后，点击新浪图标，oauth连接/授权/关联新浪微薄账号，取得用户的相关微薄数据，上一张完成之后的页面截图就清楚些了。</p>
<p><a href="http://www.haojii.com/2011/09/rails-oauth-with-sina-weibo-tutorial/tsina_succeed/" rel="attachment wp-att-638"><img class="aligncenter size-full wp-image-638" title="tsina_succeed" src="http://www.haojii.com/blog/wp-content/uploads/tsina_succeed.png" alt="" width="455" height="376" /></a></p>
<p>步骤如下</p>
<ol>
<li>使用devise实现注册登陆功能</li>
<li>使用omniauth实现新浪微薄的oauth认证</li>
<ol>
<li>配置omniauth</li>
<li>完成新浪微薄oauth，保存access_token, access_token_secret到数据库</li>
<li>使用之前存下来的access_token, access_token_secret调用新浪API取所需要的数据</li>
</ol>
</ol>
<p>OK，下面是从创建这个rails app开始的完整步骤</p>
<p>首先是<strong>1.使用devise实现注册登陆功能</strong></p>
<pre class="brush: bash; title: ; notranslate">
&gt;rails new authentication
&gt;cd authentication

修改Gemfile
     gem 'devise'
     gem 'omniauth'
     gem 'json'

&gt;bundle install
&gt;rails g controller home index
&gt;rails g devise:install
&gt;rails generate devise User
&gt;rake db:migrate

修改config/routes.rb
    root :to =&gt; &quot;home#index&quot;
修改app/views/home/index.html.erb，显示注册、登陆、退出等URL
    &lt;% if user_signed_in? -%&gt; &lt;!-- Provided by devise --&gt;
	&lt;div style=&quot;float:right&quot;&gt;
	  &lt;%= current_user.email %&gt; |
	  &lt;%= link_to '用户信息', edit_user_registration_path %&gt; |
	  &lt;%= link_to '退出登录', destroy_user_session_path, :method =&gt; :delete %&gt; |
	&lt;/div&gt;
    &lt;% end -%&gt;
    &lt;% unless user_signed_in? -%&gt;
	&lt;div style=&quot;float:right&quot;&gt;
	  &lt;%= link_to '注册', new_user_registration_path %&gt; |
	  &lt;%= link_to '登录', new_user_session_path %&gt;
	&lt;/div&gt;
    &lt;% end -%&gt;

&gt;rails s
</pre>
<p>devise真的很好用，这步骤做完之后，基本的注册登陆功能已经完备，可以访问http://localhost:3000 验证一下</p>
<p>接下来<strong>2.使用omniauth实现新浪微薄的oauth认证</strong><br />
A. 配置omniauth</p>
<pre class="brush: ruby; title: ; notranslate">
修改config/application.rb
    require 'oa-oauth'
    config.middleware.use OmniAuth::Strategies::Tsina, 'APP_KEY', 'APP_SECRET'
    #可以加多个Provider，如果还需要连接其他认证
</pre>
<p>B. 完成新浪微薄oauth，保存access_token, access_token_secret到数据库<br />
使用omniauth是如此简单，你只需要加上这个link（/auth/:provider）就行了，这里的provider是tsina</p>
<pre class="brush: ruby; title: ; notranslate">
修改app/views/home/index.html.erb，增加一行
&lt;div style=&quot;float:right&quot;&gt;
 &lt;%= current_user.email %&gt; |
 &lt;%= link_to '用户信息', edit_user_registration_path %&gt; |
 &lt;%= link_to '退出登录', destroy_user_session_path, :method =&gt; :delete %&gt; |
 &lt;%= link_to image_tag(&quot;tsina_24_24.png&quot;), '/auth/tsina', :title=&gt; &quot;连接新浪微薄&quot; %&gt;
&lt;/div&gt;
</pre>
<p>OK，用户登陆完就能看到这个链接了，点一下试试看，首先是一个授权app的页面，这时候输入新浪微博的用户密码，确认授权，然后不出意外你看到的是这个效果<br />
<a href="http://www.haojii.com/2011/09/rails-oauth-with-sina-weibo-tutorial/tsina_callback/" rel="attachment wp-att-639"><img class="aligncenter size-full wp-image-639" title="tsina_callback" src="http://www.haojii.com/blog/wp-content/uploads/tsina_callback.png" alt="" width="457" height="222" /></a></p>
<p>我们再来回顾一下oAuth的流程，这个是新浪提供的一个流程图，我们正处于重定向到Callback_url这个阶段，而我们应用还没有定义回调的url<a href="http://www.haojii.com/2011/09/rails-oauth-with-sina-weibo-tutorial/oauth_flowchart/" rel="attachment wp-att-640"><img class="aligncenter size-full wp-image-640" title="oauth_flowchart" src="http://www.haojii.com/blog/wp-content/uploads/oauth_flowchart.jpg" alt="" width="690" height="700" /></a></p>
<p>OK，下一步就是定义我们的callback_url</p>
<pre class="brush: bash; title: ; notranslate">
&gt;rails g controller authorization oauth_create oauth_destroy

修改config/routes.rb
  get &quot;authorization/oauth_create&quot; #上个命令自动生成
  get &quot;authorization/oauth_destroy&quot; #同上
  match &quot;/auth/:provider/callback&quot; =&gt; &quot;authorization#oauth_create&quot; #定义callback_url
</pre>
<p>先看看oAuth成功没有，code可以简单点</p>
<pre class="brush: ruby; title: ; notranslate">
app/controllers/authorization_controller.rb
class AuthorizationController &lt; ApplicationController
  def oauth_create
    auth = request.env[&quot;omniauth.auth&quot;]
    render :text=&gt;auth.to_yaml
  end
end
</pre>
<p>再次点击新浪图标，我们能看到一堆文本信息，包括token，secret等等，说明oAuth已经成功了。</p>
<p>C. 使用之前存下来的access_token, access_token_secret调用新浪API取所需要的数据<br />
现在我们需要的数据都能取到了，然后思考一个问题，貌似我们应该把这个授权信息存下来，然后就不需要每次用户都授权一下才能取API数据。<br />
建立下面这个authorization model存授权信息</p>
<pre class="brush: bash; title: ; notranslate">
&gt;rails g model authorization provider:string uid:string user_id:integer access_token:string access_token_secret:string
</pre>
<pre class="brush: ruby; title: ; notranslate">
app/models/user.rb
class User &lt; ActiveRecord::Base
  has_many :authorizations do
     def find_or_create_by_params(params) #辅助方法，别着急，一会儿就看到怎么用的了
          provider,uid = params[:provider],params[:uid]
          access_token,access_token_secret = params[:access_token],params[:access_token_secret]

          authorization = find_or_create_by_provider_and_uid(provider,uid)
          authorization.update_attributes(params.except(:provider,:uid))
     end
  end

  #... devise stuff
end

app/models/authorization.rb
class Authorization &lt; ActiveRecord::Base
     belongs_to :user

     validates :user_id, :uid, :provider, :presence =&gt; true
     validates :uid, :uniqueness =&gt; { :scope =&gt; :provider }
end
</pre>
<p>OK,回到回调方法里，我们要把有用的数据存到model里进而持久化</p>
<pre class="brush: ruby; title: ; notranslate">
app/controllers/authorization_controller.rb
class AuthorizationController &lt; ApplicationController
  def oauth_create
    auth = request.env[&quot;omniauth.auth&quot;]
    user = current_user
    user.authorizations.find_or_create_by_params({ #这里调用辅助方法
	:provider =&gt; auth[&quot;provider&quot;],
	:uid =&gt; auth[&quot;uid&quot;],
	:access_token =&gt; auth['credentials']['token'],
	:access_token_secret =&gt; auth['credentials']['secret']
    })
    flash[:notice] = &quot;#{auth['provider']} user #{auth['uid']} successfully authenticated&quot;
    redirect_to root_url
end
</pre>
<p>然后我们希望每次用户刷新首页的时候，我们去取一下他授权微薄的最新信息（home#index是我们的root_url还记得不）</p>
<pre class="brush: ruby; title: ; notranslate">
class HomeController &lt; ApplicationController
  def index
	oauth_retrive
  end

private
	require 'json'
	def oauth_retrive
		user = current_user
		if not user.blank?
			authorization = user.authorizations.first
			if not authorization.blank?
				access_token = authorization.access_token
				access_token_secret = authorization.access_token_secret

				consumer = OAuth::Consumer.new('APP_KEY','APP_SECRET',{:site =&gt;'http://api.t.sina.com.cn'})
				accesstoken = OAuth::AccessToken.new(consumer, access_token, access_token_secret)
				response = accesstoken.get(&quot;http://api.t.sina.com.cn/account/verify_credentials.json&quot;)
				@weibo_user = JSON.parse(response.body)
			end
		end
	end
end
</pre>
<p>&nbsp;</p>
<pre class="brush: ruby; title: ; notranslate">
修改app/views/home/index.html.erb，增加读取weibo_user的信息
&lt;% if user_signed_in? -%&gt; &lt;!-- Provided by devise --&gt;
	&lt;div style=&quot;float:right&quot;&gt;
	  &lt;%= current_user.email %&gt; |
	  &lt;%= link_to '用户信息', edit_user_registration_path %&gt; |
	  &lt;%= link_to '退出登录', destroy_user_session_path, :method =&gt; :delete %&gt; |
	  &lt;%= link_to image_tag(&quot;tsina_24_24.png&quot;), '/auth/tsina', :title=&gt; &quot;连接新浪微薄&quot; %&gt;
	&lt;/div&gt;
	&lt;% if @weibo_user %&gt;
	&lt;div style=&quot;clear:both&quot;&gt;&lt;/div&gt;
	&lt;div style=&quot;float:right&quot;&gt;
		&lt;p&gt;已连接新浪微薄:&lt;p/&gt;
		&lt;%= link_to image_tag(@weibo_user['profile_image_url']), &quot;http://weibo.com/#{@weibo_user['id']}&quot; %&gt;
		&lt;%= link_to @weibo_user['screen_name'], &quot;http://weibo.com/#{@weibo_user['id']}&quot; %&gt;
		关注:&lt;%= @weibo_user['followers_count'] %&gt;
		粉丝:&lt;%= @weibo_user['friends_count'] %&gt;
		微薄:&lt;%= @weibo_user['statuses_count'] %&gt;
		收藏:&lt;%= @weibo_user['favourites_count'] %&gt;
	&lt;/div&gt;
	&lt;% end -%&gt;
&lt;% end -%&gt;
</pre>
<p>按照这个步骤，就能成功看到最终成果了。<br />
<a href="http://www.haojii.com/2011/09/rails-oauth-with-sina-weibo-tutorial/tsina_succeed/" rel="attachment wp-att-638"><img class="aligncenter size-full wp-image-638" title="tsina_succeed" src="http://www.haojii.com/blog/wp-content/uploads/tsina_succeed.png" alt="" width="455" height="376" /></a></p>
<p><strong>Notes:</strong>上文所用的环境如下,完整代码可以在这找到<a href="https://github.com/jihao/rails_apps_for_fun/tree/master/authentication" target="_blank">https://github.com/jihao/rails_apps_for_fun/tree/master/authentication</a></p>
<pre class="brush: bash; title: ; notranslate">
Rails 3.0.9
ruby 1.8.7 (2011-02-18 patchlevel 334) [i386-mingw32]
builder (2.1.2)
devise (1.4.2)
omniauth (0.2.6)
</pre>
<p>这个过程中找到的较好的参考文档/资源</p>
<ol>
<li><a href="https://github.com/plataformatec/devise" target="_blank">https://github.com/plataformatec/devise</a></li>
<li><a href="http://oauth.rubyforge.org/" target="_blank">http://oauth.rubyforge.org/</a></li>
<li><a href="https://github.com/intridea/omniauth" target="_blank">https://github.com/intridea/omniauth</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.haojii.com/2011/09/rails-oauth-with-sina-weibo-tutorial/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>技巧-用迅雷打开某些打不开的种子文件</title>
		<link>http://www.haojii.com/2011/08/tip-download-a-bitcomet-only-torrent-file-with-thunder/</link>
		<comments>http://www.haojii.com/2011/08/tip-download-a-bitcomet-only-torrent-file-with-thunder/#comments</comments>
		<pubDate>Mon, 29 Aug 2011 14:13:54 +0000</pubDate>
		<dc:creator>Jacky</dc:creator>
				<category><![CDATA[杂项]]></category>
		<category><![CDATA[技巧]]></category>
		<category><![CDATA[高手必备]]></category>

		<guid isPermaLink="false">http://www.haojii.com/?p=629</guid>
		<description><![CDATA[有些时候我们从网上找到一个极具诱惑力的资源的种子，但是不幸的发现最猛的吸血迅雷却打不开这个torrent文件，非常非常的痛苦，这个时候不得不退而求其次，装个相对差一点的BitComet，发现种子文件竟然可以打开了，心情豁然开朗，但是坑爹的是等了半天竟然没有速度，这时候大家的心情我懂的！ 这个问题的root cause应该是种子文件被修改，只能特定BT下载客户端才能识别了，八成是为了抵制吸血迅雷，这个时候大家一定都是想，要是能用吸血迅雷打开这个种子该多好啊！ 好吧！Hold住！免费传授大家这招，在BitComet的你正在下载的这个任务上，右键-&#62;复制磁链，然后到迅雷里新建任务-&#62;粘贴，是不是成功了？速度也有了！ 也许可以写个脚本生成Magnet URI？今天就不研究了。]]></description>
			<content:encoded><![CDATA[<p>有些时候我们从网上找到一个极具诱惑力的资源的种子，但是不幸的发现最猛的吸血迅雷却打不开这个torrent文件，非常非常的痛苦，这个时候不得不退而求其次，装个相对差一点的BitComet，发现种子文件竟然可以打开了，心情豁然开朗，但是坑爹的是等了半天竟然没有速度，这时候大家的心情我懂的！</p>
<p>这个问题的root cause应该是种子文件被修改，只能特定BT下载客户端才能识别了，八成是为了抵制吸血迅雷，这个时候大家一定都是想，要是能用吸血迅雷打开这个种子该多好啊！</p>
<p>好吧！Hold住！免费传授大家这招，在BitComet的你正在下载的这个任务上，右键-&gt;复制磁链，然后到迅雷里新建任务-&gt;粘贴，是不是成功了？速度也有了！</p>
<p>也许可以写个脚本生成Magnet URI？今天就不研究了。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.haojii.com/2011/08/tip-download-a-bitcomet-only-torrent-file-with-thunder/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>git如何merge github forked repository里的代码更新?</title>
		<link>http://www.haojii.com/2011/08/how-to-git-merge-from-forked-repository/</link>
		<comments>http://www.haojii.com/2011/08/how-to-git-merge-from-forked-repository/#comments</comments>
		<pubDate>Sat, 20 Aug 2011 13:49:14 +0000</pubDate>
		<dc:creator>Jacky</dc:creator>
				<category><![CDATA[小问题]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[gmail]]></category>

		<guid isPermaLink="false">http://www.haojii.com/?p=630</guid>
		<description><![CDATA[问题是这样的，github里有个项目ruby-gmail，我需要从fork自同一个项目的另一个repository拿一些Bug Fix的代码 link1：https://github.com/dcparker/ruby-gmail （原作者dcparker的repository） link2：https://github.com/jihao/ruby-gmail （我从link1 fork的repository） link3：https://github.com/geoffyoungs/ruby-gmail （geoffyoungs 从link1 fork的repository，然后他有些Bug修改，但是没被merge回原作者的link1的repository） 也就我git clone repository到本地后，发现link3有我想要的代码，我要把link3上的改动merge到我的repository上，避免我花精力改相同的bug git如何merge github forked repository里的更新? 具体做法是下面三步，以前没用git这么搞过，知道之后其实蛮简单 1. &#62;git remote add geoffyoungs http://github.com/geoffyoungs/ruby-gmail.git 2. &#62;git fetch geoffyoungs 3. &#62;git merge geoffyoungs/master 本地的repository看上去是这样的： &#62;git remote -v geoffyoungs http://github.com/geoffyoungs/ruby-gmail.git (fetch) &#8230; <a href="http://www.haojii.com/2011/08/how-to-git-merge-from-forked-repository/">继续阅读 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>问题是这样的，github里有个项目ruby-gmail，我需要从fork自同一个项目的另一个repository拿一些Bug Fix的代码<br />
link1：<a href="https://github.com/dcparker/ruby-gmail" target="_blank">https://github.com/dcparker/ruby-gmail</a> （原作者dcparker的repository）<br />
link2：<a href="https://github.com/jihao/ruby-gmail" target="_blank">https://github.com/jihao/ruby-gmail</a> （我从link1 fork的repository）<br />
link3：<a href="https://github.com/geoffyoungs/ruby-gmail" target="_blank">https://github.com/geoffyoungs/ruby-gmail</a> （geoffyoungs 从link1 fork的repository，然后他有些Bug修改，但是没被merge回原作者的link1的repository）</p>
<p>也就我git clone repository到本地后，发现link3有我想要的代码，我要把link3上的改动merge到我的repository上，避免我花精力改相同的bug</p>
<p><strong>git如何merge github forked repository里的更新?</strong><br />
<strong>具体做法是下面三步，以前没用git这么搞过，知道之后其实蛮简单</strong><br />
<strong> <code>1. &gt;git remote add geoffyoungs http://github.com/geoffyoungs/ruby-gmail.git<br />
2. &gt;git fetch geoffyoungs<br />
3. &gt;git merge geoffyoungs/master</code></strong></p>
<p>本地的repository看上去是这样的：<br />
<code>&gt;git remote -v<br />
geoffyoungs http://github.com/geoffyoungs/ruby-gmail.git (fetch)<br />
geoffyoungs http://github.com/geoffyoungs/ruby-gmail.git (push)<br />
origin http://jihao@github.com/jihao/ruby-gmail.git (fetch)<br />
origin http://jihao@github.com/jihao/ruby-gmail.git (push)<br />
&gt;git branch -a<br />
* master<br />
remotes/geoffyoungs/gh-pages<br />
remotes/geoffyoungs/master<br />
remotes/origin/HEAD -&gt; origin/master<br />
remotes/origin/adimircolen-master<br />
remotes/origin/gh-pages<br />
remotes/origin/master<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.haojii.com/2011/08/how-to-git-merge-from-forked-repository/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>基于arduino和ruby的gmail邮件提醒</title>
		<link>http://www.haojii.com/2011/08/gmail-notification-build-upon-arduino-and-ruby/</link>
		<comments>http://www.haojii.com/2011/08/gmail-notification-build-upon-arduino-and-ruby/#comments</comments>
		<pubDate>Fri, 19 Aug 2011 14:13:45 +0000</pubDate>
		<dc:creator>Jacky</dc:creator>
				<category><![CDATA[Ruby On Rails]]></category>
		<category><![CDATA[arduino]]></category>
		<category><![CDATA[gmail]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.haojii.com/?p=625</guid>
		<description><![CDATA[基于arduino和ruby的gmail邮件提醒，我要实现的功能是gmail收到新邮件的时候，arduino板子的红色LED灯亮30秒，同时蜂鸣器叫5声 晚上折腾了一会儿，连调成功了，现在收到新邮件的时候，桌面上的arduino板子会有声有色的提醒啦，有图有真相，O(∩_∩)O哈哈~，下面分享这个小玩具是怎么搞定的。 这个玩具由两部分组成 1.PC端检查gmail邮件更新和发送串口信号的ruby脚本 2.Arduino的信号控制及串口通信程序 1.PC端检查gmail邮件更新和发送串口信号的ruby脚本 用到两个ruby gem &#8216;ruby-gmail&#8217;和&#8217;serialport&#8217; 前者封装了操作gmail邮件的相关功能，后者是一个跨平台的ruby串口通信库 ruby代码比较简单，就不多解释了 2.Arduino的信号控制及串口通信程序 为了有声有色，混合了fade和buzzer两个功能，所以代码略多 PIN 9，是绿色LED渐明渐暗的控制，显示系统正在正常工作 PIN 10，是红色LED，当收到串口H信号的时候亮起来，指示收到新邮件 PIN 6，蜂鸣器的控制针脚 其余的应该都能看懂意思，不解释了 最后总结一下： 虽然刚刚ruby入门，但是感觉用ruby写点小东西满顺畅的，还有就是github,ruby gem神马的都很强大 然后就是arduino的开发上手也很容易]]></description>
			<content:encoded><![CDATA[<p>基于arduino和ruby的gmail邮件提醒，我要实现的功能是gmail收到新邮件的时候，arduino板子的红色LED灯亮30秒，同时蜂鸣器叫5声</p>
<p>晚上折腾了一会儿，连调成功了，现在收到新邮件的时候，桌面上的arduino板子会有声有色的提醒啦，有图有真相，O(∩_∩)O哈哈~，下面分享这个小玩具是怎么搞定的。</p>
<p><a href="http://www.haojii.com/2011/08/gmail-notification-build-upon-arduino-and-ruby/arduino_gmail/" rel="attachment wp-att-626"><img class="aligncenter size-full wp-image-626" title="arduino_gmail" src="http://www.haojii.com/blog/wp-content/uploads/arduino_gmail.jpg" alt="" width="800" height="598" /></a></p>
<p>这个玩具由两部分组成<br />
1.PC端检查gmail邮件更新和发送串口信号的ruby脚本<br />
2.Arduino的信号控制及串口通信程序</p>
<p><strong>1.PC端检查gmail邮件更新和发送串口信号的ruby脚本</strong><br />
用到两个ruby gem &#8216;ruby-gmail&#8217;和&#8217;serialport&#8217;<br />
前者封装了操作gmail邮件的相关功能，后者是一个跨平台的ruby串口通信库<br />
ruby代码比较简单，就不多解释了</p>
<pre class="brush: ruby; title: ; notranslate">
require 'rubygems'
require 'gmail'
require 'serialport'

$username,$password = ARGV

def init_email_count
	gmail = Gmail.new($username, $password)
	$count = gmail.inbox.count(:unread)
	puts &quot;unread email count: #{$count}&quot;
	gmail.logout
end

def has_new_email?
	latest = get_latest_email_count
	if latest!=$count
		$count = latest
		puts &quot;current email count: #{$count}&quot;
		return true
	else
		return false
	end
end

def get_latest_email_count
	print '.'
	gmail = Gmail.new($username, $password)
	latest = gmail.inbox.count(:unread)
	gmail.logout
	return latest
end

def write_serialport chr
	puts &quot;write to serial port [#{chr}]&quot;
	$sp.write chr
	#rd = sp.read
	#puts &quot;read from serial port [#{rd}]&quot;
end

init_email_count
# 0 is mapped to &quot;COM1&quot; on Windows, and 2 is COM3, 9600 is baud rate
# Arduino on serial port2 (COM3)
$sp = SerialPort.new(2, 9600)
loop do
	if has_new_email?
		write_serialport 'H'
		sleep 30
		write_serialport 'L'
	end
	sleep 5
end

#not closed
#$sp.close
</pre>
<p><strong>2.Arduino的信号控制及串口通信程序</strong><br />
为了有声有色，混合了fade和buzzer两个功能，所以代码略多</p>
<p>PIN 9，是绿色LED渐明渐暗的控制，显示系统正在正常工作<br />
PIN 10，是红色LED，当收到串口H信号的时候亮起来，指示收到新邮件<br />
PIN 6，蜂鸣器的控制针脚</p>
<p>其余的应该都能看懂意思，不解释了</p>
<pre class="brush: cpp; title: ; notranslate">
int brightness = 0;    // how bright the LED is
int fadeAmount = 5;    // how many points to fade the LED by
int ledPin=9;          // pin for green LED which indicates system running
int serialLedPin=10;   // pin for RED LED which indicates incoming email
int buzzerPin=6;       // pin for buzzer
int incomingByte;      // a variable to read incoming serial data into
void setup()  {
  Serial.begin(9600);
  // declare pin 9 to be an output:
  pinMode(ledPin, OUTPUT);
  pinMode(serialLedPin, OUTPUT);
  pinMode(buzzerPin,OUTPUT);//设置模拟信号IO脚模式，OUTPUT为输出
}
void beep()
{
  unsigned char i,j;//定义变量
  for(i=0;i&lt;80;i++)//输出一个频率的声音
  {
    analogWrite(buzzerPin,i);//发声音
    delay(1);//延时1ms
    analogWrite(buzzerPin,LOW);//不发声音
    delay(1);//延时ms
  }
}
void beep5times()
{
   for(int i=0;i&lt;5;i++)
   {
     beep();
     delay(1000);
   }
}
void checkSerialInput() {
  // see if there's incoming serial data:
  if (Serial.available() &gt; 0) {
    // read the oldest byte in the serial buffer:
    incomingByte = Serial.read();
    Serial.write(incomingByte);
    // if it's a capital H (ASCII 72), turn on the LED:
    if (incomingByte == 'H') {
      digitalWrite(serialLedPin, HIGH);
      beep5times();
    }
    // if it's an L (ASCII 76) turn off the LED:
    if (incomingByte == 'L') {
      digitalWrite(serialLedPin, LOW);
    }
  }
}
void loop()  {
  // set the brightness of pin 9:
  analogWrite(ledPin, brightness);
  // check any input from serial in
  checkSerialInput();

  // change the brightness for next time through the loop:
  brightness = brightness + fadeAmount;

  // reverse the direction of the fading at the ends of the fade:
  if (brightness == 0 || brightness == 255) {
    fadeAmount = -fadeAmount ;
  }
  // wait for 30 milliseconds to see the dimming effect
  delay(30);
}
</pre>
<p>最后总结一下：<br />
虽然刚刚ruby入门，但是感觉用ruby写点小东西满顺畅的，还有就是github,ruby gem神马的都很强大<br />
然后就是arduino的开发上手也很容易</p>
]]></content:encoded>
			<wfw:commentRss>http://www.haojii.com/2011/08/gmail-notification-build-upon-arduino-and-ruby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ruby入门-模块</title>
		<link>http://www.haojii.com/2011/08/start-ruby-module/</link>
		<comments>http://www.haojii.com/2011/08/start-ruby-module/#comments</comments>
		<pubDate>Thu, 11 Aug 2011 15:58:37 +0000</pubDate>
		<dc:creator>Jacky</dc:creator>
				<category><![CDATA[Ruby On Rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.haojii.com/?p=620</guid>
		<description><![CDATA[Ruby模块的用法 1.Mix-in 2.namespace Ruby不允许多重继承 Ruby可以继承多个模块 方法调用的查找顺序 对象的单态方法 对象的实例方法 include模块中的实例方法 父类中的实例方法 父类include模块中的实例方法 一直这样找到最上层，如果还是没有找到，Ruby会调用默认Object#method_missing，产生NoMethodError异常]]></description>
			<content:encoded><![CDATA[<p>Ruby模块的用法 1.Mix-in 2.namespace</p>
<ul>
<li>Ruby不允许多重继承</li>
<li>Ruby可以继承多个模块</li>
</ul>
<pre class="brush: ruby; title: ; notranslate">
#foobar_module.rb
module FooBarModule     #用module关键字来定义模块
     def say
         puts 'hi'
     end
end

#foo.rb
require &quot;foobar_module&quot;     #如何在不同文件中，需要使用require或者load来加载模块
class Foo
     include FooBarModule    #可以理解为，把Module的内容拷贝一份到类里
     def bar
         puts 'foobar'
     end
end
foo = Foo.new
foo.say #hi
Foo.ancestors #=&gt; [Foo, FooBarModule, Object, Kernel]     #模块的include是一种特殊的继承
FooBarModule.respond_to? :new     #=&gt; false 模块不能实例化
FooBarModule.respond_to? :extend  #=&gt; true  模块可以继承模块，模块不能直接继承Object
</pre>
<p><strong>方法调用的查找顺序</strong></p>
<ol>
<li>对象的单态方法</li>
<li>对象的实例方法</li>
<li>include模块中的实例方法</li>
<li>父类中的实例方法</li>
<li>父类include模块中的实例方法</li>
<li>一直这样找到最上层，如果还是没有找到，Ruby会调用默认Object#method_missing，产生NoMethodError异常</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.haojii.com/2011/08/start-ruby-module/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ruby入门-类和对象-对比视图</title>
		<link>http://www.haojii.com/2011/08/start-ruby-class-object-compare-perspective/</link>
		<comments>http://www.haojii.com/2011/08/start-ruby-class-object-compare-perspective/#comments</comments>
		<pubDate>Wed, 10 Aug 2011 15:04:35 +0000</pubDate>
		<dc:creator>Jacky</dc:creator>
				<category><![CDATA[Ruby On Rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.haojii.com/?p=608</guid>
		<description><![CDATA[\ Ruby Code Notes 类 类定义 实例方法 method1 类方法 java中的static方法 单态方法 单态方法是指不隶属于某个类，而直接隶属于某个实例的方法 单态类 单态类是指只有特定实例才隶属的类，比如上面的bar这个实例所隶属的类 类方法 类方法=Class对象的单态方法 元类 Class对象的单态类就是元类]]></description>
			<content:encoded><![CDATA[<table width="1024">
<thead>
<tr>
<td width="8%">\</td>
<td width="70%">Ruby Code</td>
<td width="22%">Notes</td>
</tr>
</thead>
<tbody>
<tr>
<td>类</td>
<td>
<pre class="brush: ruby; title: ; notranslate">
class Foo
     def method1
          puts &quot;I am instance method1&quot;
     end
end
</pre>
</td>
<td>类定义</td>
</tr>
<tr>
<td>实例方法</td>
<td></td>
<td>method1</td>
</tr>
<tr>
<td>类方法</td>
<td>
<pre class="brush: ruby; title: ; notranslate">
class Foo
     def Foo.method1
          puts &quot;I am class method1&quot;
     end
end
</pre>
</td>
<td>java中的static方法</td>
</tr>
<tr>
<td><span style="color: #99cc00;">单态方法</span></td>
<td>
<pre class="brush: ruby; title: ; notranslate">
bar = Foo.new
def bar.method2
     puts &quot;I am singleton method2&quot;
end
bar2 = Foo.new
bar.method2    #I am singleton method2
bar2.method2   #NoMethodError: undefined method `method2' for #
</pre>
</td>
<td>单态方法是指不隶属于某个类，而直接隶属于某个实例的方法</td>
</tr>
<tr>
<td><span style="color: #99cc00;">单态类</span></td>
<td>
<pre class="brush: ruby; title: ; notranslate">
bar = Foo.new
class &lt;&lt; bar
     def method2
          puts &quot;I am singleton method2 defined in singleton class&quot;
     end
end
bar.method2    #I am singleton method2 defined in singleton class
</pre>
</td>
<td>单态类是指只有特定实例才隶属的类，比如上面的bar这个实例所隶属的类</td>
</tr>
<tr>
<td><span style="color: #ff0000;">类方法</span></td>
<td>
<pre class="brush: ruby; title: ; notranslate">
class Foo
     def Foo.method1 #与单态方法的定义表达式相似&quot;def (对象).(方法名)&quot;
          puts &quot;I am class method1&quot;
     end
end
</pre>
</td>
<td>类方法=Class对象的单态方法</td>
</tr>
<tr>
<td><span style="color: #ff0000;">元类</span></td>
<td>
<pre class="brush: ruby; title: ; notranslate">
class Foo
     class &lt;&lt; self #定义self(=Foo)的单态类，等同于 class &lt;&lt; Foo
          def method1
              puts &quot;I am class method1 defined in metaclass(Foo)&quot;
          end
     end
end
Foo.method1 #I am class method1 defined in metaclass(Foo)
</pre>
</td>
<td>Class对象的单态类就是元类</td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.haojii.com/2011/08/start-ruby-class-object-compare-perspective/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

