<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title></title>
    <description></description>
    <link>/</link>
    <atom:link href="/feed.xml" rel="self" type="application/rss+xml" />
    
      <item>
        <title>Tips and Resources For Setting Up Website From Ground Up</title>
        <description>&lt;p&gt;This is a summary of the whole procedure of How to build your own website using Rails Framework. It sounds really simple in the Rails Guide, but if really want to go over the whole procedure, there are steps beyond writing a small App that runs on your own computer. It is kind of a summary that reminds me things I need to care about when running a serious App in production environment, so I think it suits people who just learn how to build Rails App while want to know more about how to actually run it in production environment.
This Topic covers all this contents below:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Simple Rails App &amp;amp; Github&lt;/li&gt;
  &lt;li&gt;Domain, DNS &amp;amp; Server&lt;/li&gt;
  &lt;li&gt;Deployment&lt;/li&gt;
  &lt;li&gt;Web Server &amp;amp; App Server&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In the future there might have:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Database&lt;/li&gt;
  &lt;li&gt;Cache &amp;amp; Queue&lt;/li&gt;
  &lt;li&gt;Security&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But for now I’m only focusing on getting through the most basic steps.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;1simple-rails-app--github&quot;&gt;1.Simple Rails App &amp;amp; Github&lt;/h3&gt;

&lt;p&gt;If you already familiar with Rails and Github, just ignore this first step.&lt;/p&gt;

&lt;p&gt;Build a Toy Rails App is probably the most easy part of this article, just follow the detailed &lt;a href=&quot;http://guides.rubyonrails.org/getting_started.html&quot;&gt;Getting Started with Rails&lt;/a&gt; article here. To follow up, please go over it and I’m assuming you now have a code repository called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;blog&lt;/code&gt; on your own computer, and with command line &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rails s&lt;/code&gt; you can run it and view it in browser with address &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;localhost:3000&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you consider Rails too fancy for you and you just care about building static website (e.g.: for blog), use &lt;a href=&quot;http://jekyllrb.com/docs/quickstart/&quot;&gt;Jekyll&lt;/a&gt; is also a nice choice to get started, with this guide you can setup a toy &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;blog&lt;/code&gt; repository in seconds, and view in with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;localhost:4000&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To set up production environment, you also need &lt;a href=&quot;https://git-scm.com/book/en/v2/Getting-Started-About-Version-Control&quot;&gt;Version Control&lt;/a&gt;, nowadays most web developers use Git, you can use git with &lt;a href=&quot;https://github.com/&quot;&gt;Github&lt;/a&gt;, or you can set your own &lt;a href=&quot;https://about.gitlab.com/&quot;&gt;Gitlab&lt;/a&gt; Web App to manage your code, or else you can just simply use git on server solely with command line, its your choice to use which method to apply. Though this article mainly focus on using Git with Github. There is also a very nice written procedure on Github &lt;a href=&quot;https://help.github.com/categories/bootcamp/&quot;&gt;here&lt;/a&gt;, after following these guidelines you should have a github repository called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;blog&lt;/code&gt; now.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;2domain-dns--server&quot;&gt;2.Domain, DNS &amp;amp; Server&lt;/h3&gt;

&lt;p&gt;Many companies provides their own whole package of App management service, like &lt;a href=&quot;https://aws.amazon.com/&quot;&gt;Amazon AWS&lt;/a&gt;, &lt;a href=&quot;https://www.heroku.com/&quot;&gt;Heroku&lt;/a&gt; etc, and to be more advanced, people also invent a container called &lt;a href=&quot;https://www.docker.com/whatisdocker&quot;&gt;Docker&lt;/a&gt;. They are pretty good if you want to develop/copy a prototype really fast. But to some extent, for beginners, they are too much and might freaks you out with their loads of services. So let’s separate them to several basic pieces first.&lt;/p&gt;

&lt;h4 id=&quot;domain&quot;&gt;Domain&lt;/h4&gt;

&lt;p&gt;To make your project online, you need a domain, which is simply an address you have on the Internet. You can easily get a third level domain for free if you just want to publish a blog(e.g.: myblog.tumblr.com), but to get your own second level domain, you probably need to rent one. (Let me know if you can find a free one. :) ) Personally I use domain providers like &lt;a href=&quot;https://www.godaddy.com/&quot;&gt;GoDaddy&lt;/a&gt; and &lt;a href=&quot;http://www.gandi.net/&quot;&gt;Gandi&lt;/a&gt;, and I prefer Gandi more because their Interface is cleaner. To get a domain, simply go to one of this providers and rent one name you like, it won’t be too expensive for the first year. After the payment you should get a domain name like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foobar.com&lt;/code&gt;&lt;/p&gt;

&lt;h4 id=&quot;server&quot;&gt;Server&lt;/h4&gt;

&lt;p&gt;Most developers don’t use physical servers now, I suggest renting a simple virtual host, it is convenient because guys in charge of the real servers will help you fix security issues and upgrade your hardware without you even notice. Then all you need to care about is on the software side, besides, real servers are really expensive and too fancy to play with. I personally use &lt;a href=&quot;https://www.digitalocean.com/&quot;&gt;Digital Ocean&lt;/a&gt;, they use SSD hard drives and the price of minimum setting is cheap. Another popular choice is &lt;a href=&quot;https://www.linode.com/&quot;&gt;Linode&lt;/a&gt;, I think they have a longer history and some little birds of mine said that the setting of Linode server is more comprehensive. After the payment and very easy settings (If you use Digital Ocean also), you should have a Server System installed, let’s assume it is the latest stable version of Ubuntu, and in order to make your App work, you also need set up the environment for your App to run, with sudo permission it shouldn’t be hard. And the most important thing is that, now you get your own server IP address like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;123.132.213.231&lt;/code&gt;&lt;/p&gt;

&lt;h4 id=&quot;dns&quot;&gt;DNS&lt;/h4&gt;

&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Domain_Name_System&quot;&gt;DNS&lt;/a&gt;, according to Wikipedia, is short for Domain Name System, but to understand it in the most superficial way, it is the thing that connect your domain name and your IP address.&lt;/p&gt;

&lt;p&gt;There are two awesome and practical articles that can lead you through the procedure of making this connection.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-point-to-digitalocean-nameservers-from-common-domain-registrars&quot;&gt;How to Point to DigitalOcean Nameservers From Common Domain Registrars&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.digitalocean.com/community/tutorials/how-to-set-up-a-host-name-with-digitalocean&quot;&gt;How To Set Up a Host Name with DigitalOcean&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As you can observe, there are lots of good articles about server configuration on DigitalOcean, another reason I use it. After this step, you should able to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ping&lt;/code&gt; your server with the domain name like the second article said.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;3deployment&quot;&gt;3.Deployment&lt;/h3&gt;

&lt;p&gt;Most of times I use &lt;a href=&quot;https://github.com/capistrano/capistrano/blob/master/README.md&quot;&gt;Capistrano&lt;/a&gt;, the thing about Capistrano is that there is some significant difference between Capistrano 2 and Capistrano 3, to keep up
with the pace, I’ll look into details of Capistrano 3 here. FYI, there is also a deploy tool called &lt;a href=&quot;https://github.com/mina-deploy/mina&quot;&gt;Mina&lt;/a&gt; that is getting popular.&lt;/p&gt;

&lt;p&gt;After install Capistrano via the &lt;a href=&quot;https://github.com/capistrano/capistrano#installation&quot;&gt;Official Guide&lt;/a&gt;, there are three files you need to change. I’ve detailed comment the configuration usage in the code below.&lt;/p&gt;

&lt;h4 id=&quot;capfile&quot;&gt;/Capfile&lt;/h4&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# Load DSL and Setup Up Stages&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;capistrano/setup&apos;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Includes default deployment tasks&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;capistrano/deploy&apos;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Includes tasks from other gems included in your Gemfile&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# For documentation on these, see for example:&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#   https://github.com/capistrano/rvm&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#   https://github.com/capistrano/rbenv&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#   https://github.com/capistrano/chruby&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#   https://github.com/capistrano/bundler&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#   https://github.com/capistrano/rails&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# require &apos;capistrano/rvm&apos;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# require &apos;capistrano/rbenv&apos;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# require &apos;capistrano/chruby&apos;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Add bundler support&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;capistrano/bundler&apos;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Add assets precompile support&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;capistrano/rails/assets&apos;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Add database migration support&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;capistrano/rails/migrations&apos;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Add unicorn support&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;capistrano3/unicorn&apos;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Loads custom tasks from `lib/capistrano/tasks&apos; if you have any defined.&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;Dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;glob&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;lib/capistrano/tasks/*.rake&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h4 id=&quot;deployrb&quot;&gt;/deploy.rb&lt;/h4&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# config valid only for Capistrano 3.4&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;lock&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;3.4.0&apos;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# set the directory the code deployed to on server&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# # Default deploy_to directory is /var/www/my_app&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:deploy_to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;/your_project&apos;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# set your user name on server&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;username&quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# set the application name&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:application&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;app_name&apos;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# set the repository address&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:repo_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;git@github.com:app_name.git&apos;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# set the deployed branch&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Default branch is :master&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp }.call&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:branch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;your_branch&quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# files we want sym linking to specific entries in shared.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Default value for :linked_files is []&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:linked_files&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%w{config/database.yml config/secrets.yml}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# dirs we want symlinking to shared&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Default value for linked_dirs is []&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:linked_dirs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%w{log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system lib/data}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Set application environment&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:rails_env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;production&quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Set deploy method&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:deploy_via&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:copy&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#########################################&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Set this configurations if you don&apos;t have sudo permission&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Deploy without using sudo if you are not sudo&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:use_sudo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# set tmp dir to your home directory(when you have no sudo permission)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:tmp_dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/home/users/your_username/tmp&quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Default value for default_env is {}&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# If you installed ruby locally(in your home directory, you need to specify its location to Capistrano)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:default_env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;path: &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/home/users/your_username/.rvm/gems/ruby-2.1.5/wrappers:$PATH&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#########################################&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# These are default settings that you probably don&apos;t need to change&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# set software configuration management tool&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Default value for :scm is :git&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# set :scm, :git&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Deploy console log format setting&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Default value for :format is :pretty&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# set :format, :pretty&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Default value for :log_level is :debug&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# set :log_level, :debug&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# indicate use of sudo without password&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Default value for :pty is false&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# set :pty, false&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Set the number of releases you want to keep&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Default value for keep_releases is 5&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# set :keep_releases, 5&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Unicorn settings(We&apos;ll talk about it soon, just showcase the typical usage here)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:unicorn_pid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shared_path&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/tmp/pids/unicorn.pid&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:unicorn_config_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;config/unicorn.rb&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:unicorn_rack_env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;deployment&apos;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# &quot;development&quot;, &quot;deployment&quot;, or &quot;none&quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:deploy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;desc&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Restart application&apos;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:restart&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;on&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;roles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;in: :sequence&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;wait: &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;invoke&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;unicorn:legacy_restart&apos;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;after&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:publishing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;deploy:restart&apos;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;after&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:finishing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;s1&quot;&gt;&apos;deploy:cleanup&apos;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# After deploy cleanup, clean up old version dependencies.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:bundle&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:clean&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;on&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;roles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:web&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;within&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;release_path&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;rails_env: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:rails_env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;execute&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:bundle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:clean&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;after&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;deploy:cleanup&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;bundle:clean&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h4 id=&quot;configdeployproductionrb&quot;&gt;/config/deploy/production.rb&lt;/h4&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# set deploy stage to production&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:stage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:production&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# add your domain name and username on server&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;server&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;mydomain.com&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;roles: &lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;%w{web app db}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;user: &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;username&apos;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Then you’re all set on production deploy configuration.&lt;/p&gt;

&lt;h3 id=&quot;4web-server--app-server&quot;&gt;4.Web Server &amp;amp; App Server&lt;/h3&gt;

&lt;p&gt;The easiest way is to use &lt;a href=&quot;https://www.phusionpassenger.com/&quot;&gt;Passenger&lt;/a&gt;, the typical way is to use &lt;a href=&quot;https://www.nginx.com/&quot;&gt;Nginx&lt;/a&gt;+&lt;a href=&quot;https://github.com/defunkt/unicorn&quot;&gt;Unicorn&lt;/a&gt;, besides Passenger and Unicorn, &lt;a href=&quot;https://github.com/puma/puma&quot;&gt;Puma&lt;/a&gt; is also a popular app server choice. Here I would describe how to set up Nginx+Unicorn on server.&lt;/p&gt;

&lt;p&gt;First one need to install Nginx on server and unicorn gem, notice here that unicorn is a gem that should be part of the dependency of your Rails App, while Nginx is a popular web server that can work with lots of frameworks beyond Rails. After installation, there are three files that is important for configuration, I’ve commented the important part in the code below&lt;/p&gt;

&lt;p&gt;Some of comments originally from other people’s scripts, the references are listed below. Thanks if any of you see this. :)&lt;/p&gt;

&lt;p&gt;References:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.linode.com/docs/websites/nginx/how-to-configure-nginx&quot;&gt;How to Configure Nginx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.gotealeaf.com/blog/setting-up-your-production-server-with-nginx-and-unicorn&quot;&gt;Setting Up Your Production Server With Nginx and Unicorn&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://qiita.com/katsuhiko/items/90cb84033c305df2238b&quot;&gt;Capistrano3 を使って Rails4 + unicorn + nginx + rbenv にデプロイする&lt;/a&gt;&lt;/p&gt;

&lt;h4 id=&quot;unicornrb&quot;&gt;unicorn.rb&lt;/h4&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# Sample verbose configuration file for Unicorn (not Rack)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# This configuration file documents many features of Unicorn&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# that may not be needed for some applications. See&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# http://unicorn.bogomips.org/examples/unicorn.conf.minimal.rb&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# for a much simpler configuration file.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# See http://unicorn.bogomips.org/Unicorn/Configurator.html for complete&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# documentation.&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# app path in production environment&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;app_path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;dirname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;dirname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;pwd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Use at least one worker per core if you&apos;re on a dedicated server,&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# more will usually help for _short_ waits on databases/caches.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# But to be honest, for a small app 2 process is enough.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;worker_processes&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;ENV&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;RAILS_ENV&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;production&apos;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Since Unicorn is never exposed to outside clients, it does not need to&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# run on the standard HTTP port (80), there is no reason to start Unicorn&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# as root unless it&apos;s from system init scripts.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# If running the master process as root and the workers as an unprivileged&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# user, do this to switch euid/egid in the workers (also chowns logs):&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# user &quot;unprivileged_user&quot;, &quot;unprivileged_group&quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Help ensure your application will always spawn in the symlinked&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# &quot;current&quot; directory that Capistrano sets up.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# working_directory &quot;/path/to/app/current&quot;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# available in 0.94.0+&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;working_directory&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;app_path&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/current&quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# listen on both a Unix domain socket and a TCP port,&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# we use a shorter backlog for quicker failover when busy&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;listen&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;app_path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;/shared/tmp/sockets/unicorn.sock&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;backlog: &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;64&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# For development, you may want to listen on port 3000 so that&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# you can make sure your unicorn.rb file is soundly configured.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;backlog: &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ENV&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;RAILS_ENV&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;development&apos;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# default timeout is 60 seconds&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;timeout&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Set the location of the unicorn pid file. This should match what we put in the&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# unicorn init script later.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;app_path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;/shared/tmp/pids/unicorn.pid&apos;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# You should define your stderr and stdout here. If you don&apos;t, stderr defaults&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# to /dev/null and you&apos;ll lose any error logging when in daemon mode.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;stderr_path&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;app_path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;/shared/log/unicorn.stderr.log&apos;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;stdout_path&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;app_path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;/shared/log/unicorn.stdout.log&apos;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# combine Ruby 2.0.0 dev or REE with &quot;preload_app true&quot; for memory savings&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# http://rubyenterpriseedition.com/faq.html#adapt_apps_for_cow&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;preload_app&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;GC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;respond_to?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:copy_on_write_friendly&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt;
  &lt;span class=&quot;no&quot;&gt;GC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;copy_on_write_friendly&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Enable this flag to have unicorn test client connections by writing the&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# beginning of the HTTP headers before calling the application.  This&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# prevents calling the application for connections that have disconnected&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# while queued.  This is only guaranteed to detect clients on the same&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# host unicorn runs on, and unlikely to detect disconnects even on a&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# fast LAN.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;check_client_connection&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# local variable to guard against running a hook multiple times&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;run_once&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;before_fork&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;worker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# the following is highly recomended for Rails + &quot;preload_app true&quot;&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# as there&apos;s no need for the master process to hold a connection&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;defined?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Base&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Base&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;connection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;disconnect!&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# Occasionally, it may be necessary to run non-idempotent code in the&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# master before forking.  Keep in mind the above disconnect! example&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# is idempotent and does not need a guard.&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;run_once&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# do_something_once_here ...&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;run_once&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# prevent from firing again&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# The following is only recommended for memory/DB-constrained&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# installations.  It is not needed if your system can house&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# twice as many worker_processes as you have configured.&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;#&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# This allows a new master process to incrementally&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# phase out the old master process with SIGTTOU to avoid a&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# thundering herd (especially in the &quot;preload_app false&quot; case)&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# when doing a transparent upgrade.  The last worker spawned&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# will then kill off the old master process with a SIGQUIT.&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# old_pid = &quot;#{server.config[:pid]}.oldbin&quot;&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# if old_pid != server.pid&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;#   begin&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;#     sig = (worker.nr + 1) &amp;gt;= server.worker_processes ? :QUIT : :TTOU&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;#     Process.kill(sig, File.read(old_pid).to_i)&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;#   rescue Errno::ENOENT, Errno::ESRCH&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;#   end&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# end&lt;/span&gt;


  &lt;span class=&quot;c1&quot;&gt;# Throttle the master from forking too quickly by sleeping.  Due&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# to the implementation of standard Unix signal handlers, this&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# helps (but does not completely) prevent identical, repeated signals&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# from being lost when the receiving process is busy.&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# sleep 1&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;after_fork&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;worker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# per-process listener ports for debugging/admin/migrations&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# addr = &quot;127.0.0.1:#{9293 + worker.nr}&quot;&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# server.listen(addr, :tries =&amp;gt; -1, :delay =&amp;gt; 5, :tcp_nopush =&amp;gt; true)&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# the following is *required* for Rails + &quot;preload_app true&quot;,&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;defined?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Base&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Base&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;establish_connection&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# if preload_app is true, then you may also want to check and&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# restart any other shared sockets/descriptors such as Memcached,&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# and Redis.  TokyoCabinet file handles are safe to reuse&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# between any number of forked children (assuming your kernel&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# correctly implements pread()/pwrite() system calls)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h4 id=&quot;nginxconf&quot;&gt;nginx.conf&lt;/h4&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# This goes to /etc/nginx/nginx.conf (or where nginx is installed)&lt;/span&gt;

user www-data&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
worker_processes 2&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
pid /var/run/nginx.pid&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

events &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  worker_connections 768&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

http &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;c&quot;&gt;##&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;# Basic Settings&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;##&lt;/span&gt;

  sendfile on&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  tcp_nopush on&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  tcp_nodelay off&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  keepalive_timeout 65&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  types_hash_max_size 2048&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  server_tokens off&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;c&quot;&gt;# server_names_hash_bucket_size 64;&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;# server_name_in_redirect off;&lt;/span&gt;

  include /etc/nginx/mime.types&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  default_type application/octet-stream&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;c&quot;&gt;##&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;# Logging Settings&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;##&lt;/span&gt;

  access_log /var/log/nginx/access.log&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  error_log /var/log/nginx/error.log&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;c&quot;&gt;##&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;# Gzip Settings&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;##&lt;/span&gt;

  &lt;span class=&quot;nb&quot;&gt;gzip &lt;/span&gt;on&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  gzip_disable &lt;span class=&quot;s2&quot;&gt;&quot;msie6&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  gzip_vary on&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  gzip_proxied any&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  gzip_min_length 500&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  gzip_http_version 1.1&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;c&quot;&gt;##&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;# Unicorn Rails&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;##&lt;/span&gt;

  upstream unicorn &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    server unix:/your_project/current/tmp/sockets/unicorn.sock &lt;span class=&quot;nv&quot;&gt;fail_timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;c&quot;&gt;##&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;# Virtual Host Configs&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;##&lt;/span&gt;
  include /etc/nginx/sites-enabled/&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h4 id=&quot;default&quot;&gt;default&lt;/h4&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# This file goes to /etc/nginx/sites-available/default&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Then create a soft symlink of this file in /etc/nginx/sites-enabled/default&lt;/span&gt;

server &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  listen 80&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  server_name your_domain.name&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  root /your_project/current/public&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  client_max_body_size 1G&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  keepalive_timeout 300&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  try_files &lt;span class=&quot;nv&quot;&gt;$uri&lt;/span&gt;/index.html &lt;span class=&quot;nv&quot;&gt;$uri&lt;/span&gt;.html &lt;span class=&quot;nv&quot;&gt;$uri&lt;/span&gt; @unicorn&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  location @unicorn &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    proxy_set_header X-Forward-For &lt;span class=&quot;nv&quot;&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    proxy_set_header Host &lt;span class=&quot;nv&quot;&gt;$http_host&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    proxy_set_header X-Forward_Proto &lt;span class=&quot;nv&quot;&gt;$scheme&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    proxy_redirect off&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# This passes requests to unicorn, as defined in /etc/nginx/nginx.conf&lt;/span&gt;
    proxy_pass http://unicorn&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    proxy_read_timeout 300s&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    proxy_send_timeout 300s&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;c&quot;&gt;# You can override error pages by redirecting the requests to a file in your&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;# application&apos;s public folder, if you so desire:&lt;/span&gt;

  error_page 500 502 503 504 /500.html&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  location &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /500.html &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    root /your_project/current/public&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

  error_page 404 /404.html&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    location &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /404.html &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    root /your_project/current/public&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;There are lots of instructions of the server configuration procedure because servers run in various environments, the code above showcase the most typical configuration from my perspective.&lt;/p&gt;

&lt;p&gt;After complete all these configurations, restart nginx server and deploy your code again, then your site should properly running now.&lt;/p&gt;
</description>
        <pubDate>Mon, 14 Sep 2015 11:37:37 -0400</pubDate>
        <link>/2015/09/14/set-up-website-from-ground-up.html</link>
        <guid isPermaLink="true">/2015/09/14/set-up-website-from-ground-up.html</guid>
      </item>
    
      <item>
        <title>How to Install CRF++ on Server Without Sudo Permisson</title>
        <description>&lt;p&gt;&lt;a href=&quot;https://taku910.github.io/crfpp/&quot;&gt;CRF++&lt;/a&gt; is a API that implements &lt;a href=&quot;https://en.wikipedia.org/wiki/Conditional_random_field&quot;&gt;Conditional random field&lt;/a&gt; technique, it also has a Python API. It is used in one of my projects and I need to install in on server without sudo permission, the author didn’t specify how to do that in detail. So I think it might be helpful to share my experience, here is how to do this:&lt;/p&gt;

&lt;h4 id=&quot;1-install-python-in-home-directory&quot;&gt;1. Install Python in home directory&lt;/h4&gt;

&lt;p&gt;With sudo permission one can easily install Python using one line command, but without that, Python can be installed to, just a little bit trickier, first download the specific version of Python under &lt;a href=&quot;https://www.python.org/downloads/source/&quot;&gt;Python Source Releases&lt;/a&gt;, here I chose Python 2.7.10:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;wget https://www.python.org/ftp/python/2.7.10/Python-2.7.10.tar.xz
&lt;span class=&quot;nb&quot;&gt;tar&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-xvf&lt;/span&gt; Python-2.7.10.tar.xz
&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;Python-2.7.10&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;There is a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;configure&lt;/code&gt; script under the unzipped directory and it helps generate make files and check dependencies. If execute:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;./configure &lt;span class=&quot;nt&quot;&gt;--help&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;There will be information like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;Installation directories:
  &lt;span class=&quot;nt&quot;&gt;--prefix&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;PREFIX         &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;architecture-independent files &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;PREFIX
                          &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;/usr/local]
  &lt;span class=&quot;nt&quot;&gt;--exec-prefix&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;EPREFIX   &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;architecture-dependent files &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;EPREFIX
                          &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;PREFIX]

By default, &lt;span class=&quot;s1&quot;&gt;&apos;make install&apos;&lt;/span&gt; will &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;all the files &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;&apos;/usr/local/bin&apos;&lt;/span&gt;, &lt;span class=&quot;s1&quot;&gt;&apos;/usr/local/lib&apos;&lt;/span&gt; etc.  You can specify
an installation prefix other than &lt;span class=&quot;s1&quot;&gt;&apos;/usr/local&apos;&lt;/span&gt; using &lt;span class=&quot;s1&quot;&gt;&apos;--prefix&apos;&lt;/span&gt;,
&lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;instance &lt;span class=&quot;s1&quot;&gt;&apos;--prefix=$HOME&apos;&lt;/span&gt;.&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Because without sudo permission one usually can’t write to /usr/local/ dir, so here I changed the prefix, notice you need to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mkdir&lt;/code&gt; yourself, configure won’t do that for you:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;./configure &lt;span class=&quot;nt&quot;&gt;--prefix&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$HOME&lt;/span&gt;/local/python&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Then compile python with make files generated:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;make
make &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;After the installation, check if success:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$HOME&lt;/span&gt;/local/python/bin/python &lt;span class=&quot;nt&quot;&gt;--version&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; Python 2.7.10&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;If want to set it as the default python version, one need to change the import path in profile(my default profile is  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.bash_profile&lt;/code&gt;) by add line below:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PATH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$HOME&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/local/bin/python:&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PATH&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Then check if success:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;source&lt;/span&gt; .bash_profile
python &lt;span class=&quot;nt&quot;&gt;--version&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; Python 2.7.10
which python
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; /your_home_dir/local/python/bin/python&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h4 id=&quot;2-install-crf&quot;&gt;2. Install CRF++&lt;/h4&gt;

&lt;p&gt;First download CRF++ source file from &lt;a href=&quot;https://taku910.github.io/crfpp/&quot;&gt;here&lt;/a&gt;, I’m using version 0.58. Then go into the unzipped file, install with prefix just as described above:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;./configure &lt;span class=&quot;nt&quot;&gt;--prefix&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$HOME&lt;/span&gt;/local/CRF++
make
make &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$HOME/local/CRF++/bin&lt;/code&gt; is where command &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crf_learn&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crf_test&lt;/code&gt; in, so don’t forget to add local CRF++ bin path in profile file:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PATH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$HOME&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/local/CRF++/bin:&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PATH&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Then test if CRF++ is correctly installed:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;source&lt;/span&gt; .bash_profile
which crf_learn
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; /your_home_dir/local/CRF++/bin/crf_learn&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h4 id=&quot;3-install-crf-python-api&quot;&gt;3. Install CRF++ python API&lt;/h4&gt;

&lt;p&gt;After both Python and CRF++ is successfully installed, now we can install the python API, first &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cd&lt;/code&gt; in the python dir under CRF++ install package, and there are files like these:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;CRFPP.py
CRFPP_wrap.cxx
README
setup.py
test.py&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;After reading the file &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setup.py&lt;/code&gt; script, apparently the auther is using &lt;a href=&quot;https://docs.python.org/2/distutils/apiref.html#distutils.core.Extension&quot;&gt;distutils.core.Extension&lt;/a&gt; to add the C-Extension files in python, the original code is like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;c1&quot;&gt;#!/usr/bin/env python
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;distutils.core&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Extension&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;

&lt;span class=&quot;nf&quot;&gt;setup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;mecab-python&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;py_modules&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;CRFPP&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;ext_modules&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Extension&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;_CRFPP&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                               &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;CRFPP_wrap.cxx&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,],&lt;/span&gt;
                               &lt;span class=&quot;n&quot;&gt;libraries&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;crfpp&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;pthread&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
                     &lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;However from the document &lt;a href=&quot;https://docs.python.org/2/extending/building.html&quot;&gt;Building C and C++ Extensions with distutils&lt;/a&gt;, the default dirs for this setup to find C include files and lib files are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/usr/local/include&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/usr/local/lib&lt;/code&gt; so we need to make change the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setup.py&lt;/code&gt; file like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;c1&quot;&gt;#!/usr/bin/env python
&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;distutils.core&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Extension&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;

&lt;span class=&quot;nf&quot;&gt;setup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;mecab-python&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;py_modules&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;CRFPP&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;ext_modules&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Extension&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;_CRFPP&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                               &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;CRFPP_wrap.cxx&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,],&lt;/span&gt;
                               &lt;span class=&quot;n&quot;&gt;include_dirs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;/your_home_dir/local/CRF++/include&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
                               &lt;span class=&quot;n&quot;&gt;library_dirs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;/your_home_dir/local/CRF++/lib&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
                               &lt;span class=&quot;n&quot;&gt;libraries&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;crfpp&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;pthread&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
                     &lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Then we can run in the directory:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;python setup.py build
python setup.py &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Then for the final step, we need to add our local CRF++ lib to the system shared path so Python can find it, the detailed explanation is in &lt;a href=&quot;http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html&quot;&gt;here&lt;/a&gt;, but basically, we just need to add this line to our profile:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;LD_LIBRARY_PATH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$HOME&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/local/CRF++/lib:&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$LD_LIBRARY_PATH&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Then again:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;source&lt;/span&gt; .bash_profile&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;To test if the python API is successfully installed:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;python
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; import CRFPP
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; CRFPP
&amp;lt;module &lt;span class=&quot;s1&quot;&gt;&apos;CRFPP&apos;&lt;/span&gt; from &lt;span class=&quot;s1&quot;&gt;&apos;/your_home_dir/local/python/lib/python2.7/site-packages/CRFPP.pyc&apos;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;That’s it, then you can just explore the usage of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CRFPP&lt;/code&gt; happily. :)&lt;/p&gt;
</description>
        <pubDate>Thu, 06 Aug 2015 13:00:28 -0400</pubDate>
        <link>/tips/2015/08/06/how-to-install-crf-on-server-without-sudo-permisson.html</link>
        <guid isPermaLink="true">/tips/2015/08/06/how-to-install-crf-on-server-without-sudo-permisson.html</guid>
      </item>
    
      <item>
        <title>Sublime Text Tips</title>
        <description>&lt;p&gt;I’ve been use Sublime Text on my Mac for 2 years now and still it has many unknown features that would surprise me now and then. However, sometimes I do forgot about features, so I write this article as a reminder of future configuration and usage guide.&lt;/p&gt;

&lt;h3 id=&quot;basic-setting&quot;&gt;Basic Setting&lt;/h3&gt;

&lt;p&gt;Normal Setting of Sublime Text is done in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Preference/Setting&lt;/code&gt; part, notice that usually one only need to adapt User setting and keep Default setting as it is.&lt;/p&gt;

&lt;p&gt;My user setting is like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;folder_exclude_patterns&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.git&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;cache&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// This three line make my code reading faster.&lt;/span&gt;
    &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;font_size&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;highlight_line&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;indent_to_bracket&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// I&apos;m not a very good typer so I need this, but some people may find it annoying since it keeps telling you your perfect variable name is wrongly spelled. :)&lt;/span&gt;
    &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;spell_check&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// This last three is very helpful if you really care about clean code.&lt;/span&gt;
    &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;translate_tabs_to_spaces&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;trim_trailing_white_space_on_save&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;ensure_newline_at_eof_on_save&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;setup-command-line&quot;&gt;Setup command line&lt;/h3&gt;

&lt;p&gt;Next step is to open files and directories from command line using Sublime Text, the installation didn’t do it for you so you need to do it by yourself, luckily it is not hard at all. :)&lt;/p&gt;

&lt;p&gt;According to the documentation &lt;a href=&quot;http://www.sublimetext.com/docs/2/osx_command_line.html&quot;&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What you need to do is simply:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;ln&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/Applications/Sublime Text 2.app/Contents/SharedSupport/bin/subl&quot;&lt;/span&gt; ~/bin/subl&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;But you also need be careful about your bash profile configuration, make sure to add /usr/local/bin in your export PATH and if you’re using zsh like me, make sure to change the configuration of zsh as well.&lt;/p&gt;

&lt;p&gt;I don’t suggest to adapt default editor in terminal to Sublime Text though, when I used it as default editor there is some saving issues I encountered.&lt;/p&gt;

&lt;h3 id=&quot;package-control&quot;&gt;Package Control&lt;/h3&gt;

&lt;p&gt;Package Control is another amazing thing about sublime text you can always find the package you want &lt;a href=&quot;https://packagecontrol.io/&quot;&gt;here&lt;/a&gt;, several packages I used most often is as below:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/khiltd/Abacus&quot;&gt;Abacus&lt;/a&gt; It’s small and it’s old, but it is useful enough for alignment.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/revolunet/sublimetext-markdown-preview&quot;&gt;Markdown Preview&lt;/a&gt; I used it a lot, it can build github-markdown-like pages.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/farcaller/DashDoc&quot;&gt;DashDoc&lt;/a&gt; Dash + Sublime Text&lt;/p&gt;

&lt;h3 id=&quot;search&quot;&gt;Search&lt;/h3&gt;

&lt;p&gt;Searching in Sublime Text is amazing, actually that’s why I fall in love with it in the first place.&lt;/p&gt;

&lt;p&gt;Search current page is basically accomplished by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Command+F&lt;/code&gt;,
You can also use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Command+P&lt;/code&gt;, where you input &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@&lt;/code&gt; sign to search for function and classes and input &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:&lt;/code&gt; sign to search line number, and input &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#&lt;/code&gt; to search anything. But I mostly use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Command+P&lt;/code&gt; to search for file names in current directory, it has super good fuzzy search support so basically you can type anything in your head and it will help you open the file you want.&lt;/p&gt;

&lt;p&gt;To search words in files, the command you need is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Command+Shift+F&lt;/code&gt;, notice that it also support regular expression search by press &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Alt+Command+R&lt;/code&gt; (after press &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Command+Shift+F&lt;/code&gt;), case sensitive search by press &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Alt+Command+C&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can also use fuzzy search on file locations too, you can put &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/dir/, *.csv&lt;/code&gt; as your search location and then it will only do search in csv files.&lt;/p&gt;

&lt;h3 id=&quot;another-trivial-tip&quot;&gt;Another trivial tip&lt;/h3&gt;

&lt;p&gt;To bulid your code(I’m refering to simple snippit here) from the editor, simply push &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Command+B&lt;/code&gt;, you can also write your own build method if you like. I write my own tcl build method (What is &lt;a href=&quot;http://www.tcl.tk/&quot;&gt;tcl&lt;/a&gt;?) for instance.&lt;/p&gt;

&lt;h3 id=&quot;whats-next&quot;&gt;What’s next&lt;/h3&gt;

&lt;p&gt;I learned most of the tricks in &lt;a href=&quot;https://sublime-text-unofficial-documentation.readthedocs.org/en/latest/index.html&quot;&gt;Sublime Text Unofficial Documentation&lt;/a&gt;, hope to learn more as time goes by.&lt;/p&gt;
</description>
        <pubDate>Sun, 22 Jun 2014 00:00:00 -0400</pubDate>
        <link>/tips/2014/06/22/sublime_text_tips.html</link>
        <guid isPermaLink="true">/tips/2014/06/22/sublime_text_tips.html</guid>
      </item>
    
      <item>
        <title>Learning Compiler -- Semantic Analysis, CodeGen and Optimization</title>
        <description>&lt;h4 id=&quot;this-is-the-summary-of-stanford-compiler-lessons-on-coursera&quot;&gt;This is the summary of &lt;a href=&quot;https://class.coursera.org/compilers-004/&quot; title=&quot;Coursera Compiler&quot;&gt;Stanford Compiler Lessons on Coursera&lt;/a&gt;&lt;/h4&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;semantic-analysis&quot;&gt;Semantic Analysis&lt;/h3&gt;

&lt;p&gt;Semantic Analysis is used to understand the meaning of code, this is the hardest part for me.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Analyse Scope&lt;/p&gt;

    &lt;p&gt;There are two kinds of scopes, static scope and dynamic scope, most languages has static scopes&lt;/p&gt;

    &lt;p&gt;In the example language Cool, there are 5 kinds of scopes:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;Class declarations (introduce class names)&lt;/li&gt;
      &lt;li&gt;Method definitions (introduce method names)&lt;/li&gt;
      &lt;li&gt;Let expressions (introduce object id’s)&lt;/li&gt;
      &lt;li&gt;Formal parameters (introduce object id’s)&lt;/li&gt;
      &lt;li&gt;Attribute definitions (introduce object id’s)&lt;/li&gt;
      &lt;li&gt;Case expressions (introduce object id’s)&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;also, methods and class names have complex scopes.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Symbol Table&lt;/p&gt;

    &lt;p&gt;A data structure that tracks the current bindings of identifiers, we can use a stack to represent it.
 we can first, build an abstract syntax tree, then use symbol table to check and bind things together, so if something is not right, we claim an error.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Types&lt;/p&gt;

    &lt;p&gt;A language’s type system specifies which operations are valid for which types. The goal of type checking is to ensure that operations are used with the correct types.&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;The types in Cool are:
        &lt;ul&gt;
          &lt;li&gt;Class Names&lt;/li&gt;
          &lt;li&gt;SELF_TYPE&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;How to configure type:
        &lt;ul&gt;
          &lt;li&gt;The user declares types for identifiers&lt;/li&gt;
          &lt;li&gt;The compiler infers types for expressions&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Type Checking&lt;/p&gt;

    &lt;p&gt;using logical rules to infer the type of one expression.&lt;/p&gt;

    &lt;p&gt;Building logical blocks:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;Symbol ^ is “and”&lt;/li&gt;
      &lt;li&gt;Symbol =&amp;gt; is “if-then”&lt;/li&gt;
      &lt;li&gt;x:T is “x has type T”&lt;/li&gt;
      &lt;li&gt;|- means “it is provable that…”&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;Notice: Types are computed in a bottom-up pass over the AST&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Type Environment&lt;/p&gt;

    &lt;p&gt;Since variables don’t have a solid type, a type environment gives
 types for free variables, or more precisely, a type environment
 is a function to transfer varaibles to Types&lt;/p&gt;

    &lt;p&gt;Let &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;O&lt;/code&gt; be a function from ObjectIdentifiers to Types&lt;/p&gt;

    &lt;p&gt;The sentence &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;O |- e: T&lt;/code&gt;&lt;/p&gt;

    &lt;p&gt;is read: Under the assumption that variables have the
 types given by O, it is provable that the expression e
 has the type T&lt;/p&gt;

    &lt;p&gt;Type environment is passed down the AST from
 the root towards the leaves, while types are computed up the AST from the leaves
 towards the root, notice the diffrerece here.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Subtyping&lt;/p&gt;

    &lt;p&gt;Define a relation called subtyping ≤ on classes&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;X ≤ X&lt;/li&gt;
      &lt;li&gt;X ≤ Y if X inherits from Y&lt;/li&gt;
      &lt;li&gt;X ≤ Z if X ≤ Y and Y ≤ Z&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lub(X,Y)&lt;/code&gt;, the least upper bound of X and Y, is Z if&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;X ≤ Z ^ Y ≤ Z, then Z is an upper bound&lt;/li&gt;
      &lt;li&gt;X ≤ Z’ ^ Y ≤ Z’ =&amp;gt; Z ≤ Z’, then Z is least among upper bounds&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;the least upper bound of two types is their least common ancestor in the inheritance tree&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Typing Methods&lt;/p&gt;

    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;M&lt;/code&gt; for method signatures, M(C,f) = (T1,…Tn,Tn+1)
 means in class C there is a method f that f(x1:T1,…,xn:Tn): Tn+1
 this is mostly used in dispatch and barely used anywhere else,but it must be added to all rules.&lt;/p&gt;

    &lt;p&gt;For some cases involving SELF_TYPE, we need to know the class in which an expression appears
 So we also defined the current class &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C&lt;/code&gt;&lt;/p&gt;

    &lt;p&gt;which sum up the rule as
 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;O,M,C |- e: T&lt;/code&gt;
 An expression &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;e&lt;/code&gt; occurring in the body of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C&lt;/code&gt; has static type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T&lt;/code&gt; given a variable type environment &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;O&lt;/code&gt; and method signatures &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;M&lt;/code&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Relation of dynamic type and static type.&lt;/p&gt;

    &lt;p&gt;Soundness theorem for the Cool type system:
 for every random E.
 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dynamic_type(E) ≤ static_type(E)&lt;/code&gt;
 which means all operations that can be used on an object of type C can also be used on an object of type C’≤ C&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;SELF_TYPE&lt;/p&gt;

    &lt;p&gt;when invoking a method, it allows the method to return type of the class(SELF_TYPE) which invoking it instead of the class contains this method.
 But remember  the declaration of method should change to&lt;/p&gt;

    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;method() : SELF_TYPE { … }&lt;/code&gt;&lt;/p&gt;
    &lt;ul&gt;
      &lt;li&gt;It is a static type&lt;/li&gt;
      &lt;li&gt;It helps the type checker to keep better track of types&lt;/li&gt;
      &lt;li&gt;It enables the type checker to accept more correct programs&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;Let T and T’ be any types but SELF_TYPE, and SELF_TYPEc ≤ C&lt;/p&gt;

    &lt;ol&gt;
      &lt;li&gt;SELF_TYPEc ≤ SELF_TYPEc&lt;/li&gt;
      &lt;li&gt;SELF_TYPEc ≤ T if C ≤ T&lt;/li&gt;
      &lt;li&gt;T ≤ SELF_TYPEc always false&lt;/li&gt;
      &lt;li&gt;T ≤ T’&lt;/li&gt;
      &lt;li&gt;lub(SELF_TYPEc, SELF_TYPEc) = SELF_TYPEc&lt;/li&gt;
      &lt;li&gt;lub(SELF_TYPEc, T) = lub(C, T)&lt;/li&gt;
      &lt;li&gt;lub(T, SELF_TYPEc) = lub(C, T)&lt;/li&gt;
      &lt;li&gt;lub(T, T’) = T&lt;/li&gt;
    &lt;/ol&gt;

    &lt;p&gt;SELF_TYPE is not always allowed in Cool&lt;/p&gt;

    &lt;ol&gt;
      &lt;li&gt;class T inherits T’ {…} where T, T’ cannot be SELF_TYPE&lt;/li&gt;
      &lt;li&gt;m@T(E1,…,En) where T cannot be SELF_TYPE&lt;/li&gt;
      &lt;li&gt;m(x : T) : T’ { … } where only T’ can be SELF_TYPE!&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Error Recovery&lt;/p&gt;

    &lt;p&gt;Introduce a new type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;No_type&lt;/code&gt; for use with ill-typed expressions&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;Define No_type ≤ C for all types C&lt;/li&gt;
      &lt;li&gt;Every operation is defined for No_type (With a No_type result)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;code-generation&quot;&gt;Code Generation&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Runtime Organization&lt;/p&gt;

    &lt;p&gt;Assume Organization in memory like a big rectangular bookshelf.&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;
        &lt;p&gt;Layers (from head(low address) to toe(high address))&lt;/p&gt;

        &lt;ul&gt;
          &lt;li&gt;First Layer contains code, for most languages, fixed size and read only&lt;/li&gt;
          &lt;li&gt;Second Layer contains static data with fixed addresses (e.g., global data)&lt;/li&gt;
          &lt;li&gt;Third Layer (Stack) contains activation records for each currently active procedure&lt;/li&gt;
          &lt;li&gt;Bottom Layer (Heap) contains dynamic data which grows to head&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Activation&lt;/p&gt;

    &lt;p&gt;An invocation of procedure P is an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;activation&lt;/code&gt; of P&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;The lifetime of an activation of P is
        &lt;ul&gt;
          &lt;li&gt;All the steps to execute P&lt;/li&gt;
          &lt;li&gt;Including all the steps in procedures P calls&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Notice:
        &lt;ul&gt;
          &lt;li&gt;Lifetimes of procedure activations are properly nested&lt;/li&gt;
          &lt;li&gt;Activation lifetimes can be depicted as a tree, which is called an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;activation tree&lt;/code&gt;&lt;/li&gt;
          &lt;li&gt;Since activations are properly nested, a stack can track currently active procedures&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Activation Records&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;
        &lt;p&gt;The information needed to manage one procedure activation is called an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;activation record&lt;/code&gt; (AR) or frame
 &lt;strong&gt;The compiler must determine, at compile-time, the layout of activation records and generate code that correctly accesses locations in the activation record. Thus, the AR layout and the code generator must be designed together!&lt;/strong&gt;&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;Activation Records usually cantains (e.g: If procedure F calls procedure G)&lt;/p&gt;
        &lt;ul&gt;
          &lt;li&gt;Space for G’s return value&lt;/li&gt;
          &lt;li&gt;F’s actural parameters&lt;/li&gt;
          &lt;li&gt;Pointer to the previous activation record (The control link; points to AR of caller of G)&lt;/li&gt;
          &lt;li&gt;Machine status prior to calling G (Contents of registers &amp;amp; program counters and Local variables)&lt;/li&gt;
          &lt;li&gt;Other temporary values&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Code Generation&lt;/p&gt;

    &lt;p&gt;We simulate &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stack machine&lt;/code&gt; instructions using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MIPS&lt;/code&gt; instructions and registers&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;Stach Machine: a simple model for code generation, for an instruction r = F(a1…an) it
        &lt;ul&gt;
          &lt;li&gt;Pops n operands from the stack&lt;/li&gt;
          &lt;li&gt;Computes the operation F using the operands&lt;/li&gt;
          &lt;li&gt;Pushes the result r on the stack&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;MIPS (originally an acronym for Microprocessor without Interlocked Pipeline Stages) is a reduced instruction set computer (RISC) instruction set (ISA) developed by MIPS Technologies (formerly MIPS Computer Systems, Inc.).
        &lt;ul&gt;
          &lt;li&gt;Acturally we just need to get familiar with it’s instructions and registers, konwing the def. is useless nor helpful here ;)&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;MIPS registers used here are:
        &lt;ul&gt;
          &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$a0&lt;/code&gt; accumulator  (Q: why call it a0? A: just convention. Notice it’s always on the top of stack)&lt;/li&gt;
          &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$sp&lt;/code&gt; stack pointer, it contains address of the next empty location on the stack&lt;/li&gt;
          &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$t1&lt;/code&gt; temperary register&lt;/li&gt;
          &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$fp&lt;/code&gt; frame pointer, a pointer to the current activation&lt;/li&gt;
          &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$ra&lt;/code&gt; return address&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;MIPS instructions used here are:
        &lt;ul&gt;
          &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lw&lt;/code&gt; reg1 offset(reg2)  –&amp;gt; load 32-bit word from address reg2 + offset into reg1, notice offset is always an integer&lt;/li&gt;
          &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;add&lt;/code&gt; reg1 reg2 reg3    –&amp;gt; (reg1 &amp;lt;- reg2 + reg3)&lt;/li&gt;
          &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sw&lt;/code&gt; reg1 offset(reg2)  –&amp;gt; store 32-bit word in reg1 at address reg2 + offset&lt;/li&gt;
          &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;addiu&lt;/code&gt; reg1 reg2 imm   –&amp;gt; reg1 &amp;lt;- reg2 + imm, here imm means immediate value&lt;/li&gt;
          &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;li&lt;/code&gt; reg1 imm           –&amp;gt; reg1 &amp;lt;- imm&lt;/li&gt;
          &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sub&lt;/code&gt; reg1 reg2 reg3    –&amp;gt; reg1 &amp;lt;- reg2 - reg3&lt;/li&gt;
          &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;beq&lt;/code&gt; reg1 reg2 label   –&amp;gt; go to branch label if reg1 == reg2&lt;/li&gt;
          &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;b&lt;/code&gt; label               –&amp;gt; unconditional jump to label&lt;/li&gt;
          &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jar&lt;/code&gt; label             –&amp;gt; jump to label, save address of next instruction in $ra&lt;/li&gt;
          &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jr&lt;/code&gt;                    –&amp;gt; jump and link, jump to address in register reg &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;what means jump and link?&lt;/code&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Temporaries&lt;/p&gt;

    &lt;p&gt;Temporary is a fixed space in a stack for temporary values. Assign a location in the AR for each temporary can make the code much efficient.&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;Let NT(e) = # of temps needed to evaluate e:
        &lt;ul&gt;
          &lt;li&gt;NT(e1 + e2) = max(NT(e1), 1 + NT(e2))&lt;/li&gt;
          &lt;li&gt;NT(e1 - e2) = max(NT(e1), 1 + NT(e2))&lt;/li&gt;
          &lt;li&gt;NT(if e1 = e2 then e3 else e4) = max(NT(e1),1 + NT(e2), NT(e3), NT(e4))&lt;/li&gt;
          &lt;li&gt;NT(id(e1,…,en) = max(NT(e1),…,NT(en))&lt;/li&gt;
          &lt;li&gt;NT(int) = 0&lt;/li&gt;
          &lt;li&gt;NT(id) = 0&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;For a AR that has temps, a function definition f(x1,…,xn) = e has 2 + n + NT(e) elements
        &lt;ul&gt;
          &lt;li&gt;Return address (1)&lt;/li&gt;
          &lt;li&gt;(old) Frame pointer (1)&lt;/li&gt;
          &lt;li&gt;n arguments   (n)&lt;/li&gt;
          &lt;li&gt;NT(e) locations for intermediate results (NT(e))&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Object Layout&lt;/p&gt;

    &lt;p&gt;A Cool Object contains:
     + Class Tag: identifies class of a object
     + Object Size: size of an object in words
     + Dispatch ptr: a pointer to the table of pointers points to methods of this object’s class&lt;/p&gt;

    &lt;p&gt;The offset for an attributes is the same in a class and all of its subclass&lt;/p&gt;

    &lt;p&gt;The method and args in a class and its subclass is always in a fixed position, even is overwritten, so in execution the args might be different in content, but they are of the same name&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;optimization&quot;&gt;Optimization&lt;/h3&gt;

&lt;p&gt;Optimizing compilers repeat optimizations until no improvement is possible
The optimizer can also be stopped at any point to limit compilation time
Goal:  Maximum benefit for minimum cost&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Intermediate Language (IL)&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;Intermediate code gather up tp form intermidate language, which is a language between the source and the target, the biggest differece between it and assembly code is it can use any number of registers, but in other aspects it’s almost the same as assembly code thus it is also called a high level assembly code
  The form of IL is: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;t1 := y * z&lt;/code&gt;. It should be used in optimization phase because:
        &lt;ul&gt;
          &lt;li&gt;it is machine independent, means it doesn’t need to consider the structure of computer the code is running on.&lt;/li&gt;
          &lt;li&gt;Exposes optimization opportunities clearly&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;Basic block: A maximal sequence of instructions written in intermediate language with no labels (except at the first instruction), and no jumps (except in the last instruction)&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;Control Flow Graph: use basic blocks as nodes and jumps as vertexs with directions&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Optimization types:&lt;/p&gt;

    &lt;p&gt;There are three granularities of optimizations:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;Local optimizations (Apply to a basic block in isolation, mostly use)&lt;/li&gt;
      &lt;li&gt;Global optimizations (Apply to a control-flow graph (method body) in isolation, many use)&lt;/li&gt;
      &lt;li&gt;Inter-procedural optimizations (Apply across method boundaries, few use)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Local Optimization&lt;/p&gt;

    &lt;p&gt;On intermediate Language:
 It is the simplest form of optimization, it just need to optimize one basic block instead of the whole procedure body, it has these methods:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;
        &lt;p&gt;Algebraic Simplification:&lt;/p&gt;

        &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;// delete useless code:
x := x + 0
x := x * 1
// simplify statements:
x := x * 0  =&amp;gt; x := 0
y := y ** 2 =&amp;gt; y := y * y
x := x * 8  =&amp;gt; x := x &amp;lt;&amp;lt; 3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;Constant Folding: (can be dangerous if applied in different machines)&lt;/p&gt;

        &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;x := 2 + 2 =&amp;gt; x := 4
if 2 &amp;lt; 0 jump L      // can be deleted
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;Constant propagation:&lt;/p&gt;

        &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;x := 3          x := 3
y := Z * w  =&amp;gt;  y := Z * w
q := x + y      q := 3 + y
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;Deadcode Elimination: eliminate unreachable basic blocks&lt;/p&gt;

        &lt;p&gt;E.g., basic blocks that are not the target of any jump or “fall through” from a conditional&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;Single Assignment: each register occurs only once on the left-hand side of an assignment&lt;/p&gt;

        &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;// b is a fresh register
x := z + y      b := z + y
a := x      =&amp;gt;  a := b
x := 2 * x      x := 2 * b
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;Common Subexpression Elimination:&lt;/p&gt;

        &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;// the values of x, y, and z do not change
// in the … code
x := y + z      x := y + z
…           =&amp;gt;  …
w := y + z      w := x
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;Copy Propagation:&lt;/p&gt;

        &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;// a should not appear anywhere else in the program
x := z + y      b := z + y      b := z + y
a := x      =&amp;gt;  a := b      =&amp;gt;  x := 2 * b
x := 2 * a      x := 2 * b
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;
      &lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;On Assembly Code: use Peephole Optimization, replace improved version of instructions with original instructions, also need to be applied repeatedly for maximum effect.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Wed, 21 May 2014 18:36:00 -0400</pubDate>
        <link>/study/2014/05/21/learning_compiler_summary_2.html</link>
        <guid isPermaLink="true">/study/2014/05/21/learning_compiler_summary_2.html</guid>
      </item>
    
      <item>
        <title>Learning Compiler -- Intro, Lexical Analysis and Parsing</title>
        <description>&lt;h4 id=&quot;this-is-the-summary-of-stanford-compiler-lessons-on-coursera&quot;&gt;This is the summary of &lt;a href=&quot;https://class.coursera.org/compilers-004/&quot; title=&quot;Coursera Compiler&quot;&gt;Stanford Compiler Lessons on Coursera&lt;/a&gt;&lt;/h4&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;intro&quot;&gt;Intro&lt;/h3&gt;

&lt;p&gt;The basic steps of compile is&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;lexical analysis&lt;/li&gt;
  &lt;li&gt;parsing&lt;/li&gt;
  &lt;li&gt;semantic analysis&lt;/li&gt;
  &lt;li&gt;optimization&lt;/li&gt;
  &lt;li&gt;code generation&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;lexical-analysis&quot;&gt;Lexical Analysis&lt;/h3&gt;

&lt;p&gt;the implementation of lexical analysis contains two things:&lt;/p&gt;

&lt;p&gt;first, partition the input string into lexemes&lt;/p&gt;

&lt;p&gt;Second, identify the token class of each lexeme&lt;/p&gt;

&lt;p&gt;Notice that this method mostly use Left-to-right scan, and lookahead sometimes is required.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Token Class(In COOL)&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;whitespace: : a non-empty sequence of blanks, newlines, and tabs&lt;/li&gt;
      &lt;li&gt;keyword: “if” or “else” or “then” or …&lt;/li&gt;
      &lt;li&gt;identifier: strings of letters or digits, starting with a letter&lt;/li&gt;
      &lt;li&gt;integer: a non-empty string of digits&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Regular Language&lt;/p&gt;

    &lt;p&gt;The regular expressions over ∑ are the smallest set of expressions including&lt;/p&gt;

    &lt;p&gt;In regular languages there are rules descirbed in sets like:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;ℇ     (Epsilon)&lt;/li&gt;
      &lt;li&gt;‘c’   (Single Charactor)&lt;/li&gt;
      &lt;li&gt;A + B (Union)&lt;/li&gt;
      &lt;li&gt;AB    (Concatation)&lt;/li&gt;
      &lt;li&gt;A*    (Iteration)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Formal Language&lt;/p&gt;

    &lt;p&gt;Let ∑ be a set of characters (an alphabet). A language over ∑ is a set of strings of characters drawn from ∑
 It is represeted as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;L(e) = M&lt;/code&gt;, where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;e&lt;/code&gt; stands for regular expression, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;M&lt;/code&gt; stands for set of strings.
 In formal languages I’ve learned that multiple syntaxs of regular language can only point to one semantic meaning, which is the formal language.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Lexical Specification&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;Procedure:
        &lt;ol&gt;
          &lt;li&gt;Write a rexp for the lexemes of each token class&lt;/li&gt;
          &lt;li&gt;Construct formal language L(R), matching all lexemes for all tokens&lt;/li&gt;
          &lt;li&gt;Let input be x1…xn For 1 ≤ i ≤ n check x1…xn ∊ L(R)&lt;/li&gt;
          &lt;li&gt;If success, then we know that x1…xi ∊ L(Rj) for some j&lt;/li&gt;
          &lt;li&gt;Remove x1…xi from input and go to (3)&lt;/li&gt;
          &lt;li&gt;return ERROR token if all strings are not in the lexical specification&lt;/li&gt;
        &lt;/ol&gt;
      &lt;/li&gt;
      &lt;li&gt;Notice:
        &lt;ul&gt;
          &lt;li&gt;one regular expression should match as long as a string can be.&lt;/li&gt;
          &lt;li&gt;regular expression’s priority is determined by the specified order.&lt;/li&gt;
          &lt;li&gt;An Error match should always have the lowest priority&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Finite Automata&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;A finite automaton consists of
        &lt;ul&gt;
          &lt;li&gt;An input alphabet ∑&lt;/li&gt;
          &lt;li&gt;A set of states S&lt;/li&gt;
          &lt;li&gt;A start state n&lt;/li&gt;
          &lt;li&gt;A set of accepting states F ⊆ S&lt;/li&gt;
          &lt;li&gt;A set of transitions s1 (on input a) -&amp;gt; s2&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Deterministic Finite Automata (DFA)
        &lt;ul&gt;
          &lt;li&gt;One transition per input per state&lt;/li&gt;
          &lt;li&gt;No ℇ-moves&lt;/li&gt;
          &lt;li&gt;Faster to execute&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Nondeterministic Finite Automata (NFA)
        &lt;ul&gt;
          &lt;li&gt;Can have multiple transitions for one input in a given state (which may ends in different results)&lt;/li&gt;
          &lt;li&gt;Can have ℇ-moves&lt;/li&gt;
          &lt;li&gt;In general, smaller than DFA&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Implementing Finite Automata&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;
        &lt;p&gt;Procedure: Lexical Specification -&amp;gt; Regular Expressions -&amp;gt; NFA -&amp;gt; DFA -&amp;gt; Table-driven Implementation of DFA&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;NFA -&amp;gt; DFA
        &lt;ul&gt;
          &lt;li&gt;Epsilon Closure: Pick one state, then look at all the states it can reach by following epsilon moves.&lt;/li&gt;
          &lt;li&gt;So basically the transition is about finding epsilon closures in NFA of different inputs, then gather each epsilon closure up as one DFA state.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;A DFA can be implemented by a 2D table T (Acturally NFA can also do the trick,but the table would be huge…)
        &lt;ul&gt;
          &lt;li&gt;One dimension is states&lt;/li&gt;
          &lt;li&gt;Other dimension is input symbol&lt;/li&gt;
          &lt;li&gt;For every transition Si (on input a) -&amp;gt; Sk, define T[i,a] = k&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;parsing&quot;&gt;Parsing&lt;/h3&gt;

&lt;p&gt;Finite Automata can really only express things where you can count modulus on k, where k is the number of states.&lt;/p&gt;

&lt;p&gt;So we need parsing, which transfer sequence of tokens from lexer to parse tree of the program.&lt;/p&gt;

</description>
        <pubDate>Tue, 01 Apr 2014 13:09:00 -0400</pubDate>
        <link>/study/2014/04/01/learning_compiler_summery_1.html</link>
        <guid isPermaLink="true">/study/2014/04/01/learning_compiler_summery_1.html</guid>
      </item>
    
  </channel>
</rss>
