<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8477445975588753706</id><updated>2012-02-01T11:24:40.864-08:00</updated><title type='text'>Standards</title><subtitle type='html'>Blogged by Ujihisa. Standard methods of programming and thoughts including Ruby, Vim, LLVM, Haskell and Mathematics written by a Japanese programmer.
&lt;a href="http://github.com/ujihisa"&gt;github/ujihisa&lt;/a&gt;</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default?start-index=101&amp;max-results=100'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>178</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-474495087501324491</id><published>2012-01-22T12:04:00.001-08:00</published><updated>2012-01-24T10:25:44.226-08:00</updated><title type='text'>AutoKey Rocks</title><content type='html'>&lt;p&gt;Mac OS X has a built-in keyboard shortcut configuration tool in Preferences. You can set both global key bindings and application-specific key bindings.&lt;/p&gt;
&lt;p&gt;I had used this to use Cmd key more often than Ctrl key. For example Google Chrome has default key mappings to go to the next tab by &lt;code&gt;&amp;lt;ctrl-tab&amp;gt;&lt;/code&gt; and to the previous tab by &lt;code&gt;&amp;lt;shift-ctrl-tab&amp;gt;&lt;/code&gt;. They break your left pinky easily. I mapped them ad &lt;code&gt;&amp;lt;Cmd-j&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;Cmd-k&amp;gt;&lt;/code&gt;. That helped the finger.&lt;/p&gt;
&lt;p&gt;But there is no such great built-in tool in the Linux world neither in Gnome nor KDE. There is a Keyboard Shortcuts in Preference of Gnome, but it's only for Gnome apps.&lt;/p&gt;
&lt;h2 id="autokey"&gt;AutoKey&lt;/h2&gt;
&lt;p&gt;AutoKey is a similar tool to the Mac OS X built-in keybinding configuration tool. The differences are (1) AutoKey doesn't map a key to a function in the application's menu and (2) AutoKey enables you to run arbitrary scripts.&lt;/p&gt;
&lt;p&gt;It's very easy to install on Debian family distributions such as Ubuntu. Gentoo, on the other hand, has an overlay that has autokey-gtk package, but it's broken. You have to get the source code and build it. It also requires you to install some dependencies manually, but it works.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img src="http://cache.gyazo.com/df0a1bcb43c0543b7bea4efcb539ce7a.png" alt="autokey-gtk on gentoo" /&gt;&lt;p class="caption"&gt;autokey-gtk on gentoo&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="added-on-jan-24-2012"&gt;(Added on Jan 24 2012)&lt;/h2&gt;
&lt;p&gt;There is an issue in autokey that you cannot exclude a window easily. See the end of this discussion to solve it. &lt;a href="http://groups.google.com/group/autokey-users/browse_thread/thread/658ad02cfbde8788"&gt;&lt;code class="url"&gt;http://groups.google.com/group/autokey-users/browse_thread/thread/658ad02cfbde8788&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-474495087501324491?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/474495087501324491/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2012/01/autokey-rocks.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/474495087501324491'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/474495087501324491'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2012/01/autokey-rocks.html' title='AutoKey Rocks'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-6984912327034710100</id><published>2011-12-26T01:14:00.001-08:00</published><updated>2011-12-26T01:14:22.612-08:00</updated><title type='text'>Compiling a Language to Whitespace</title><content type='html'>&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Whitespace_(programming_language)"&gt;Whitespace&lt;/a&gt; is a widely-known instruction set on a stack-machine virtual machine.&lt;/p&gt;
&lt;p&gt;The below is a sample hello world in Whitespace intermediate language. I added some notes that begin with #.&lt;/p&gt;
&lt;table width="100%"&gt;&lt;tr valign="top"&gt;
  &lt;td width="50%"&gt;&lt;pre wrap="wrap"&gt;
Push 0
Push 72
Store
# storing the value 72 to 0th heap
Push 1
Push 101
Store
# storing the value 101 to 1st heap
Push 2
Push 108
Store
Push 3
Push 108
Store
Push 4
Push 111
Store
Push 5
Push 44
Store
Push 6
Push 32
Store
Push 7
Push 119
Store
Push 8
Push 111
Store
Push 9
Push 114
Store
Push 10
Push 108
Store
Push 11
Push 100
Store
Push 12
Push 32
Store
Push 13
Push 111
Store
Push 14
Push 102
Store
Push 15
Push 32
Store
Push 16
Push 115
Store
Push 17
Push 112
Store
Push 18
Push 97
Store
Push 19
Push 99
Store
Push 20
Push 101
Store
Push 21
Push 115
Store
# (cont.d...)
&lt;/pre&gt;&lt;/td&gt;
  &lt;td width="50%"&gt;&lt;pre wrap="wrap"&gt;
Push 22
Push 33
Store
Push 23
Push 0
Store
Push 0
Call "\t \t  \t\t   \t \t\t\t \t  \t \t\t  \t  \t\t\t \t\t\t \t\t\t "
# Jumping to the ☃ mark with remembering this place to return later
Call "\t \t  \t\t  \t\t\t \t\t \t  \t \t\t   \t\t \t\t \t\t\t \t\t\t \t \t  \t\t  \t\t\t \t\t "
# Jumping to the ☁ mark with remembering this place to return later
End
# Terminating program.
Label "  \t  \t\t   \t  \t\t \t    \t\t "
Infix Plus
Return
Label "\t \t  \t\t   \t \t\t\t \t  \t \t\t  \t  \t\t\t \t\t\t \t\t\t "
# ☃
Dup
# Copying the top value of the stack. It's 0 (if you see here for the first time.)
Retrieve
# Getting the 0th value of the heap. It's 72 (if you see here for the first time.)
Dup
If Zero "  \t  \t\t  \t\t\t \t\t \t \t  \t\t \t\t\t\t\t \t \t \t  \t\t   \t \t\t\t \t  \t \t\t  \t  \t\t\t \t\t\t \t\t\t "
OutputChar
Push 1
Infix Plus
Jump "\t \t  \t\t   \t \t\t\t \t  \t \t\t  \t  \t\t\t \t\t\t \t\t\t "
Label "  \t  \t\t  \t\t\t \t\t \t \t  \t\t \t\t\t\t\t \t \t \t  \t\t   \t \t\t\t \t  \t \t\t  \t  \t\t\t \t\t\t \t\t\t "
Discard
Discard
Return
# Ending the function call and going back to the previous place.
Label "  \t  \t\t \t    \t\t \t \t  \t\t  \t  \t\t\t "
Dup
Dup
ReadChar
Retrieve
Dup
Push 10
Infix Minus
If Zero "  \t  \t\t  \t\t\t \t\t \t \t  \t\t \t\t\t\t\t \t   \t  \t\t \t    \t\t \t \t  \t\t  \t  \t\t\t "
Discard
Push 1
Infix Plus
Jump "  \t  \t\t \t    \t\t \t \t  \t\t  \t  \t\t\t "
Label "  \t  \t\t  \t\t\t \t\t \t \t  \t\t \t\t\t\t\t \t   \t  \t\t \t    \t\t \t \t  \t\t  \t  \t\t\t "
Discard
Push 1
Infix Plus
Push 0
Store
Return
Label "\t \t  \t\t  \t\t\t \t\t \t  \t \t\t   \t\t \t\t \t\t\t \t\t\t \t \t  \t\t  \t\t\t \t\t "
# ☁
Push 10
Push 13
OutputChar
OutputChar
Return
&lt;/pre&gt;&lt;/td&gt;
  &lt;/tr&gt;&lt;/table&gt;


&lt;p&gt;And the result is&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Hello, world of spaces!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can run it with a little bit fixes of the official whitespace implementation &lt;a href="http://compsoc.dur.ac.uk/whitespace/download.php"&gt;wspace 0.3&lt;/a&gt; written in Haskell.&lt;/p&gt;
&lt;h2 id="a-language"&gt;A Language&lt;/h2&gt;
&lt;p&gt;I made an experimental small language and it's compiler.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(begin
  (def 0 98)
  (f 90 7)
  (putc (ref 0))
  (end)
  (defn f (x y)
        (putc (g x y)))
  (defn g (x y)
        (+ x y)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Syntax: an expression begins with &amp;quot;(&amp;quot; and a name, arguments for it, and end with &amp;quot;)&amp;quot;. If an expression has a value, you have to use the value with enclosing another expression. Otherwise the behavior is undefined. If an expression does not have a value, you must not enclose it as an argument. Otherwise the behavior is undefined.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;begin
&lt;ul&gt;
&lt;li&gt;combines some expressions that don't have return values&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;def {index} {value}
&lt;ul&gt;
&lt;li&gt;assigns the {value} to {index}th slot of heap&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;ref {index} -&amp;gt; {value}
&lt;ul&gt;
&lt;li&gt;returns the {value} of {index}th slot of heap&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;putc {value}
&lt;ul&gt;
&lt;li&gt;outputs a character which ASCII code is {value}&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;end
&lt;ul&gt;
&lt;li&gt;terminates program&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;defn {name} ({args}) {body}
&lt;ul&gt;
&lt;li&gt;defines a function&lt;/li&gt;
&lt;li&gt;if a program come to defn without using call, the behavior is undefined.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;* + {value} {value} -&amp;gt; {value} * obviously&lt;/p&gt;
&lt;p&gt;You can &amp;quot;call&amp;quot; a function you made just with ({name} {arg1} {arg2}). You can use arguments of the function just by an identifier like x.&lt;/p&gt;
&lt;p&gt;Sample code&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(begin
  (putc (+ 50 40))
  (end))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That is compiled to&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Push 50
Push 40
Infix Plus
OutputChar
End
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and shows 'Z'.&lt;/p&gt;
&lt;p&gt;I little bit complicated example&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(begin
  (def 0 98)
  (f 90 7)
  (putc (ref 0))
  (end)
  (defn f (x y)
        (putc (g x y)))
  (defn g (x y)
        (+ x y)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;compiled to&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Push 0
Push 98
Store
Push 90
Push 7
Call &amp;quot;f&amp;quot;
Push 0
Retrieve
OutputChar
End
Label &amp;quot;f&amp;quot;
Push (-1)
Swap
Store
Push (-2)
Swap
Store
Push (-1)
Retrieve
Push (-2)
Retrieve
Call &amp;quot;g&amp;quot;
OutputChar
Return
Label &amp;quot;g&amp;quot;
Push (-3)
Swap
Store
Push (-4)
Swap
Store
Push (-3)
Retrieve
Push (-4)
Retrieve
Infix Plus
Return
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and shows &amp;quot;ab&amp;quot;.&lt;/p&gt;
&lt;p&gt;You may have noticed that the function argument is in negative number of heaps. If you updates them like by &lt;code&gt;(def -3 100)&lt;/code&gt; it may result in breaking something, but since this implementation doesn't support negative literals, it remains safe.&lt;/p&gt;
&lt;p&gt;The compiler is below, written in Haskell.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import qualified VM as V
import qualified Text.Parsec as P
import Control.Applicative ((&amp;lt;|&amp;gt;), (&amp;lt;$&amp;gt;))
import qualified Control.Monad.State as S
import qualified Data.Map as M
import Data.Maybe (fromJust)

data Intermediate = Comment String
  | Inst V.Instruction
  | Paramdef String
  | Paramref String
  deriving Show

type LispParser = P.ParsecT String () (S.State String)
type ParamMap = M.Map String Integer

main :: IO ()
main = do
  code &amp;lt;- readFile &amp;quot;hworld.lisp&amp;quot;
  --mapM_ print $ parse code
  let runtime = compile (parse code)
  mapM_ print runtime
  putStrLn &amp;quot;--&amp;quot;
  V.vm (V.VM runtime (V.Stack []) (V.Stack []) M.empty 0)

parse :: String -&amp;gt; [Intermediate]
parse str = either (error . show) id $
  S.evalState (P.runPT parseExpr () &amp;quot;lisp&amp;quot; str) &amp;quot;toplevel&amp;quot;

parseExpr :: LispParser [Intermediate]
parseExpr = P.try parseInt
         &amp;lt;|&amp;gt; parseDefn
         &amp;lt;|&amp;gt; parseBuiltin
         &amp;lt;|&amp;gt; parseApply
         &amp;lt;|&amp;gt; parseVar

parseInt :: LispParser [Intermediate]
parseInt = do
  x &amp;lt;- P.many1 P.digit
  return [Inst $ V.Push $ read x]

parseAtom :: LispParser String
parseAtom = P.many1 $ P.noneOf &amp;quot; \t\n()&amp;quot;

parseDefn :: LispParser [Intermediate]
parseDefn = do
  P.try $ do
    ignoringSpaces $ P.char '('
    ignoringSpaces $ P.string &amp;quot;defn&amp;quot;
  fname &amp;lt;- requireSpaces parseAtom
  S.lift $ S.put fname

  ignoringSpaces $ P.char '('
  names &amp;lt;- ignoringSpaces $ parseAtom `P.sepBy` P.skipMany1 P.space
  ignoringSpaces $ P.char ')'

  body &amp;lt;- ignoringSpaces parseExpr
  ignoringSpaces $ P.char ')'
  S.lift $ S.put &amp;quot;toplevel&amp;quot;
  return $
    Comment &amp;quot;(defn&amp;quot; :
    Inst (V.Label fname) :
    map (Paramdef . ((fname ++ &amp;quot;/&amp;quot;) ++)) names ++
    body ++ [Inst V.Return] ++ [Comment &amp;quot;)&amp;quot;]

parseBuiltin :: LispParser [Intermediate]
parseBuiltin = P.try $ do
  (fname, xs) &amp;lt;- atomAndArgs
  x &amp;lt;- case (fname, length xs) of
       (&amp;quot;+&amp;quot;, 2) -&amp;gt; return [Inst $ V.Infix V.Plus]
       (&amp;quot;putc&amp;quot;, 1) -&amp;gt; return [Inst V.OutputChar]
       (&amp;quot;def&amp;quot;, 2) -&amp;gt; return [Inst V.Store]
       (&amp;quot;ref&amp;quot;, 1) -&amp;gt; return [Inst V.Retrieve]
       (&amp;quot;end&amp;quot;, 0) -&amp;gt; return [Inst V.End]
       (&amp;quot;begin&amp;quot;, _) -&amp;gt; return []
       _ -&amp;gt; fail &amp;quot;omg&amp;quot;
  return $ Comment ('(' : fname) : concat xs ++ x ++ [Comment &amp;quot;)&amp;quot;]

parseApply :: LispParser [Intermediate]
parseApply = do
  (fname, xs) &amp;lt;- atomAndArgs
  return $ concat xs ++ [Inst $ V.Call fname]

atomAndArgs :: LispParser (String, [[Intermediate]])
atomAndArgs = do
  ignoringSpaces $ P.char '('
  fname &amp;lt;- ignoringSpaces parseAtom
  xs &amp;lt;- ignoringSpaces $ parseExpr `P.sepBy` P.many1 P.space
  P.char ')'
  return (fname, xs)

parseVar :: LispParser [Intermediate]
parseVar = do
  name &amp;lt;- ignoringSpaces $ P.many1 $ P.noneOf &amp;quot; \t\n()&amp;quot;
  fname &amp;lt;- S.lift S.get
  return [Paramref $ fname ++ '/' : name]

ignoringSpaces :: LispParser a -&amp;gt; LispParser a
ignoringSpaces f = P.skipMany P.space &amp;gt;&amp;gt; f

requireSpaces :: LispParser a -&amp;gt; LispParser a
requireSpaces f = P.skipMany1 P.space &amp;gt;&amp;gt; f

compile :: [Intermediate] -&amp;gt; [V.Instruction]
compile inters = concat $ S.evalState (mapM compile' inters) M.empty

compile' :: Intermediate -&amp;gt; S.State ParamMap [V.Instruction]
compile' (Comment _) = return []
compile' (Inst x) = return [x]
compile' (Paramdef name) = do
  idx &amp;lt;- pred . negate . fromIntegral . M.size &amp;lt;$&amp;gt; S.get
  S.modify $ M.insert name idx
  return [V.Push idx, V.Swap, V.Store]
compile' (Paramref name) = do
  idx &amp;lt;- fromJust . M.lookup name &amp;lt;$&amp;gt; S.get
  return [V.Push idx, V.Retrieve]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This code depends on VM.hs from wspace-0.3 to share the data structure of VM Instruction and to execute the compiled program. If you only want to compile given programs, you don't need VM.hs but just to add the following definition.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;data Instruction =
       Push Integer
     | Dup
     | Ref Int
     | Slide Int
     | Swap
     | Discard
     | Infix Op
     | Store
     | Retrieve
     | Label Label
     | Call Label
     | Jump Label
     | If Test Label
     | Return
     | OutputChar
     | OutputNum
     | ReadChar
     | ReadNum
     | End
   deriving (Show,Eq)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By the way wspace-0.3 had an issue that it can only handle sequential indices of heap. You can store values in 0th, 1st and 2nd slots of heap, but you cannot store in 100th without completing all indices between 0 to 100. I wrote a patch to allow any index. Feel free to use it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;diff --git VM.hs VM.hs
index c9e96ab..bb74374 100644
--- VM.hs
+++ VM.hs
@@ -1,6 +1,8 @@
 module VM where

 import IO
+import qualified Data.Map as M
+import Data.Maybe (fromJust)

 {- Stack machine for running whitespace programs -}

@@ -35,7 +37,7 @@ type Loc = Integer

 type Program = [Instruction]
 newtype Stack = Stack [Integer]
-type Heap = [Integer]
+type Heap = M.Map Integer Integer

 data VMState = VM {
         program :: Program,
@@ -130,13 +132,7 @@ findLabel' m (_:xs) i = findLabel' m xs (i+1)
 -- Heap management

 retrieve :: Integer -&amp;gt; Heap -&amp;gt; IO Integer
-retrieve x heap = return (heap!!(fromInteger x))
+retrieve x heap = return $ fromJust $ M.lookup x heap

 store :: Integer -&amp;gt; Integer -&amp;gt; Heap -&amp;gt; IO Heap
-store x 0 (h:hs) = return (x:hs)
-store x n (h:hs) = do hp &amp;lt;- store x (n-1) hs
-             return (h:hp)
-store x 0 [] = return (x:[])
-store x n [] = do hp &amp;lt;- store x (n-1) [] 
-         return (0:hp)
-
+store x n h = return $ M.insert n x h
&lt;/code&gt;&lt;/pre&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-6984912327034710100?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/6984912327034710100/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2011/12/compiling-language-to-whitespace.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/6984912327034710100'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/6984912327034710100'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2011/12/compiling-language-to-whitespace.html' title='Compiling a Language to Whitespace'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-5678922555223148197</id><published>2011-12-22T22:13:00.001-08:00</published><updated>2011-12-22T22:22:17.980-08:00</updated><title type='text'>Continuous-Passing Conversion in Haskell</title><content type='html'>&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Continuation-passing_style"&gt;&lt;code class="url"&gt;http://en.wikipedia.org/wiki/Continuation-passing_style&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Convert from&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(+ (f 0 (g 1)) 2)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;to&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(g' (lambda (r0) (f' (lambda (r1) (+ r1 2)) 0 r0)) 1)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;where data structure internally in Haskell is like&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;data AST = Node [AST] | Leaf Value
data Value = IntVal Int | Plus | Atom String | Lambda [String]
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="implementation-and-description"&gt;Implementation and description&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;import qualified Control.Monad.State as S

data AST = Node [AST] | Leaf Value
instance Show AST where
  show (Node xs) = &amp;quot;(&amp;quot; ++ unwords (map show xs) ++ &amp;quot;)&amp;quot;
  show (Leaf v) = show v

data Value = IntVal Int | Plus | Atom String | Lambda [String]
instance Show Value where
  show (IntVal i) = show i
  show Plus = &amp;quot;+&amp;quot;
  show (Atom name) = name
  show (Lambda names) = &amp;quot;lambda (&amp;quot; ++ unwords names ++ &amp;quot;)&amp;quot;

-- (+ (f 0 (g 1)) 2)
-- (g' (lambda (r0) (f' (lambda (r1) (+ r1 2)) 0 r0)) 1)
program :: AST
program = Node [Leaf Plus,
  Node [Leaf (Atom &amp;quot;f&amp;quot;), Leaf (IntVal 0), Node [Leaf (Atom &amp;quot;g&amp;quot;), Leaf (IntVal 1)]],
  Leaf (IntVal 2)]

main = do
  print program
  print $ cps program

cps :: AST -&amp;gt; AST
cps ast =
  let (newAst, modifiers) = S.runState (cps' ast) [] in
      foldl (flip ($)) newAst modifiers

cps' :: AST -&amp;gt; S.State [AST -&amp;gt; AST] AST
cps' (Node (Leaf (Atom f) : xs)) = do
  xs' &amp;lt;- mapM cps' xs
  n &amp;lt;- length `fmap` S.get
  let name = 'r' : show n
  append $ \root -&amp;gt; Node $
    (Leaf . Atom $ f ++ &amp;quot;'&amp;quot;) :
    Node [Leaf (Lambda [name]), root] :
    xs'
  return $ Leaf (Atom name)
cps' (Node xs) = Node `fmap` mapM cps' xs
cps' c@(Leaf _) = return c

append x = S.modify (x :)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This converts correctly.&lt;/p&gt;
&lt;p&gt;I used State Monad to modify given tree. The function &lt;code&gt;cps&lt;/code&gt; starts state and the actual function &lt;code&gt;cps'&lt;/code&gt; traverses given AST subtrees recursively.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(+ (f 0 (g 1)) 2)
   ^^^^^^^^^^^
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When &lt;code&gt;cps'&lt;/code&gt; sees this subtree, oh yes the first item of the list is a user-defined function and it's not tail-call, so &lt;code&gt;cps'&lt;/code&gt; wants to replace the part with a new variable (say &lt;code&gt;r&lt;/code&gt;), and enclose whole tree with new function &lt;code&gt;f'&lt;/code&gt; and the arguments.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(f' (lambda (r) ((+ r 2) 0 (g 1))))
^^^^^^^^^^^^^^^^^   ^   ^^^^^^^^^^^
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It's easy to change subtree but it's not trivial to change outside the subtree. But fortunately we already know that we only have to enclose something around the whole tree, so you can just save a function in state.&lt;/p&gt;
&lt;p&gt;After &lt;code&gt;cps'&lt;/code&gt; process is done, you apply all functions that the state has accumulatively to enclose trees. That will complete the job.&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-5678922555223148197?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/5678922555223148197/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2011/12/continuous-passing-conversion-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/5678922555223148197'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/5678922555223148197'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2011/12/continuous-passing-conversion-in.html' title='Continuous-Passing Conversion in Haskell'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-6982389424052825129</id><published>2011-12-20T20:56:00.001-08:00</published><updated>2011-12-21T00:02:50.547-08:00</updated><title type='text'>Unlambda Interpreter in Haskell</title><content type='html'>&lt;blockquote&gt;
&lt;p&gt;Unlambda is a minimal, &amp;quot;nearly pure&amp;quot;[1] functional programming language invented by David Madore. It is based on combinatory logic, a version of the lambda calculus that omits the lambda operator. It relies mainly on two built-in functions (s and k) and an &amp;quot;apply&amp;quot; operator (written `, the backquote character). These alone make it Turing-complete, but there are also some I/O functions to make it possible to interact with the user, some shortcut functions and a function for lazy evaluation. There are no variables in the language.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Unlambda"&gt;&lt;code class="url"&gt;http://en.wikipedia.org/wiki/Unlambda&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;import qualified Text.Parsec as P
import Control.Applicative ((*&amp;gt;), (&amp;lt;$&amp;gt;), (&amp;lt;*&amp;gt;))

data AST = Apply AST AST | Val Value
instance Show AST where
  show (Apply a b) = &amp;quot;(&amp;quot; ++ show a ++ &amp;quot; &amp;quot; ++ show b ++ &amp;quot;)&amp;quot;
  show (Val (Dot c)) = &amp;quot;put-&amp;quot; ++ [c]
  show (Val (Builtin c)) = [c]

data Value = Dot Char
  | Builtin Char
  | PendingK Value
  | PendingS1 Value
  | PendingS2 Value Value
  deriving Show

main = do
  let helloworld = &amp;quot;`r```````````.H.e.l.l.o. .w.o.r.l.di&amp;quot;
  let fibonacci = &amp;quot;```s``s``sii`ki`k.*``s``s`ks``s`k`s`ks``s``s`ks``s`k`s`kr``s`k`sikk`k``s`ksk&amp;quot;
  print $ desugar $ parse helloworld
  eval $ desugar $ parse helloworld
  --eval $ desugar $ parse fibonacci

parse :: String -&amp;gt; AST
parse = either (error . show) id . P.parse parse' &amp;quot;unlambda&amp;quot;

parse' = P.try (P.char '`' *&amp;gt; (Apply &amp;lt;$&amp;gt; parse' &amp;lt;*&amp;gt; parse'))
         P.&amp;lt;|&amp;gt;
         P.try (P.char '.' *&amp;gt; (Val . Dot &amp;lt;$&amp;gt; P.anyChar))
         P.&amp;lt;|&amp;gt;
         P.try (Val . Builtin &amp;lt;$&amp;gt; P.anyChar)

desugar :: AST -&amp;gt; AST
desugar (Apply a b) = Apply (desugar a) (desugar b)
desugar (Val (Builtin 'r')) = Val (Dot '\n')
desugar (Val (Builtin 'i')) = Apply (Apply (Val (Builtin 's')) (Val (Builtin 'k'))) (Val (Builtin 'k')) -- i = ``skk
desugar x = x

eval :: AST -&amp;gt; IO (Value)
eval (Apply a b) = do
  a' &amp;lt;- eval a
  b' &amp;lt;- eval b
  apply a' b'
eval (Val x) = return x

apply :: Value -&amp;gt; Value -&amp;gt; IO Value
apply (Dot c) x = putChar c &amp;gt;&amp;gt; return x
apply (Builtin 'k') x = return $ PendingK x
apply (Builtin 's') x = return $ PendingS1 x
apply (PendingK x) y = return $ x
apply (PendingS1 x) y = return $ PendingS2 x y
apply (PendingS2 x y) z = do
  a &amp;lt;- apply x z
  b &amp;lt;- apply y z
  apply a b
&lt;/code&gt;&lt;/pre&gt;
&lt;ol style="list-style-type: decimal"&gt;
&lt;li&gt;parse the given string to abstract syntax tree&lt;/li&gt;
&lt;li&gt;desugar the ast; expanding macros like r or i.&lt;/li&gt;
&lt;li&gt;interpreter evaluates all nodes!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;AST&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(put-\n (((((((((((put-H put-e) put-l) put-l) put-o) put- ) put-w) put-o) put-r) put-l) put-d) ((s k) k)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Result of &lt;code&gt;helloworld&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Hello world
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Result of &lt;code&gt;fibonacci&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;*
*
**
***
*****
********
*************
*********************
**********************************
*******************************************************
*****************************************************************************************
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="added-at-tue-dec-20-235712-pst-2011"&gt;(added at Tue Dec 20 23:57:12 PST 2011)&lt;/h2&gt;
&lt;p&gt;I also made a stackmachine-based virtual machine and a compiler for it.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://gist.github.com/1505131"&gt;&lt;code class="url"&gt;https://gist.github.com/1505131&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This was actually much simpler/easier than I thought. There's a difference between pure interpreter and this virtualmachine, but it's not very big.&lt;/p&gt;
&lt;p&gt;For example very short program &amp;quot;hi&amp;quot; that shows &amp;quot;hi&amp;quot; is &amp;quot;``.h.ii&amp;quot; in unlambda. First this parser converts the text to AST.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;((put-h put-i) ((s k) k))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then the compiler converts the tree to sequence of instructions.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IPush (Dot 'h')
IPush (Dot 'i')
IApply
IPush (Builtin 's')
IPush (Builtin 'k')
IApply
IPush (Builtin 'k')
IApply
IApply
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then the virtualmachine runtime will run it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;hi
&lt;/code&gt;&lt;/pre&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-6982389424052825129?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/6982389424052825129/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2011/12/unlambda-interpreter-in-haskell.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/6982389424052825129'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/6982389424052825129'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2011/12/unlambda-interpreter-in-haskell.html' title='Unlambda Interpreter in Haskell'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-5276857176979593852</id><published>2011-12-18T18:29:00.001-08:00</published><updated>2011-12-18T18:29:13.279-08:00</updated><title type='text'>Read Raw POST Request Body in Compojure</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;h2 id='brief-introduction-to-compojure'&gt;Brief introduction to Compojure&lt;/h2&gt;
&lt;p&gt;Compojure gives you a shortcut to make a monofunctional web application. For example a Lingr bot is a web application that only need to be responsible with one single endpoint that handles POST request. The below is a web application that only shows "hello" in / endpoint with GET request.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defroutes hello
           (GET "/" [] "hello"))
(run-jetty hello {:port 80})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that it requires you to be the root of the system if you are going to run a web app on port 80.&lt;/p&gt;
&lt;p&gt;The main part of the app is just 3 lines of code. That reminds me of code examples for Sinatra, a Ruby web library.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;get '/' do
  'hello'
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Anyways the Compojure example code doesn't work only with the main logic. You are supposed to make a Leiningen project usually to manage the app and its dependent libraries.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ lein new hello
$ cd hello
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;project.clj&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defproject hello "1.0.0-SNAPSHOT"
            :main hello.core
            :description "FIXME: write description"
            :dependencies [[org.clojure/clojure "1.2.1"]
                           [compojure "1.0.0-RC2"]
                           [ring "1.0.1"]])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;src/hello/core.clj&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(ns hello.core
  (:use
    compojure.core
    ring.adapter.jetty))

(defroutes hello
           (GET "/" [] "hello"))
(run-jetty hello {:port 80})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;then&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ lein deps
$ lein run
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;it should work.&lt;/p&gt;
&lt;h2 id='parameters'&gt;Parameters&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;(defroutes hello
           (GET "/" [] "hello"))
(run-jetty hello {:port 80})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The 2nd argument of GET, &lt;code&gt;[]&lt;/code&gt; in this case, is parameter list for the expression you give in 3rd argument, which mostly for referring GET parameters. That's actually a hashmap that contains &lt;code&gt;:params&lt;/code&gt; key which value is also a hashmap of GET parameters. Ditto in POST.&lt;/p&gt;
&lt;p&gt;How can we get the raw post parameter?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(POST "/" {params :params} (...))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In that way you cannot get raw data because it's after the process. You can reconstruct the raw data only when the given parameter is like proper &lt;code&gt;a=1\nb=2&lt;/code&gt; form. These days some web apis are required to handle raw POST data, which is mostly in JSON, like a Lingr Bot API.&lt;/p&gt;
&lt;p&gt;The answer is in :body of the parameter, but it's not a String but a mysterious HttpParser.Input object, assuming you are using ring as the middleware.&lt;/p&gt;
&lt;p&gt;&lt;a href='http://jetty.codehaus.org/jetty/jetty-6/apidocs/org/mortbay/jetty/HttpParser.Input.html'&gt;&lt;code class='url'&gt;http://jetty.codehaus.org/jetty/jetty-6/apidocs/org/mortbay/jetty/HttpParser.Input.html&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This class looks weird because even though this has &lt;code&gt;read()&lt;/code&gt; method the return value type isn't String but int. The other &lt;code&gt;read()&lt;/code&gt; looks like you are supposed to pass a mutable data and refer the changed data.&lt;/p&gt;
&lt;p&gt;Fortunately we can use &lt;code&gt;slurp&lt;/code&gt; Clojure function to hide this complicated behaviour.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defroutes hello
           (POST "/" {body :body} (slurp body)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This shows the given raw POST parameter!&lt;/p&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-5276857176979593852?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/5276857176979593852/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2011/12/read-raw-post-request-body-in-compojure.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/5276857176979593852'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/5276857176979593852'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2011/12/read-raw-post-request-body-in-compojure.html' title='Read Raw POST Request Body in Compojure'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-8630896309591299562</id><published>2011-11-15T15:43:00.001-08:00</published><updated>2011-11-15T15:46:49.931-08:00</updated><title type='text'>Lazy List in C</title><content type='html'>&lt;pre&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;

typedef struct list_ {
  int x;
  struct closure_int_int_list_ *tail;
} *list;

typedef struct closure_int_int_list_ {
  list (*call)(int, int);
  int x1;
  int x2;
} *closure_int_int_list;

closure_int_int_list newclosure(list call(int, int), int x1, int x2)
{
  closure_int_int_list c;
  c = (closure_int_int_list)malloc(sizeof(*c));
  c-&amp;gt;call = call;
  c-&amp;gt;x1 = x1;
  c-&amp;gt;x2 = x2;
  return c;
}

list newlist(int x, closure_int_int_list tail)
{
  list xs = (list)malloc(sizeof(struct list_));
  xs-&amp;gt;x = x;
  xs-&amp;gt;tail = tail;
  return xs;
}

list listtail(list xs)
{
  if (xs-&amp;gt;tail == NULL) return NULL;
  return xs-&amp;gt;tail-&amp;gt;call(xs-&amp;gt;tail-&amp;gt;x1, xs-&amp;gt;tail-&amp;gt;x2);
}

void deletelist(list xs)
{
  free(xs-&amp;gt;tail);
  free(xs);
}

int *takelist(int num, list xs)
{
  int *array;
  int i;
  list p;
  array = (int *)malloc(sizeof(int) * num);
  p = xs;
  for (i = 0; i &amp;lt; num; ++i) {
    array[i] = p-&amp;gt;x;
    p = listtail(p);
  }
  return array;
}

list fibnext(int a, int b)
{
  return newlist(b, newclosure(fibnext, b, a + b));
}

void printarray(int *xs, int size)
{
  int i;
  for (i = 0; i &amp;lt; size; ++i) {
    printf(&amp;quot;%d &amp;quot;, xs[i]);
  }
}

int main(int argc, char const* argv[])
{
  list xs;
  int *array;
  xs = newlist(1, newclosure(fibnext, 1, 1));
  array = takelist(10, xs);
  printarray(array, 10);
  free(array);
  deletelist(xs);
  return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;result:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1 1 2 3 5 8 13 21 34 55 
&lt;/code&gt;&lt;/pre&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-8630896309591299562?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/8630896309591299562/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2011/11/include-include-typedef-struct-list-int.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/8630896309591299562'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/8630896309591299562'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2011/11/include-include-typedef-struct-list-int.html' title='Lazy List in C'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-7718093655869785281</id><published>2011-11-13T20:53:00.001-08:00</published><updated>2011-11-13T20:53:15.544-08:00</updated><title type='text'>Type Inferences of Ambiguous Literals</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;The Haskell code below works.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;main = print $ x + y
x = 1
y = 2.3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This results 3.3. &lt;code&gt;x&lt;/code&gt; isn't &lt;code&gt;Int&lt;/code&gt; because &lt;code&gt;x&lt;/code&gt; is used with &lt;code&gt;(+)&lt;/code&gt; operator that also takes 2.3.&lt;/p&gt;
&lt;p&gt;On the other hand, the code below causes a type error in compile time.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;main = print $ x + y
x = 1
y = 2.3

z = x :: Int
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;error:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;No instance for (Fractional Int)
  arising from the literal `2.3'
Possible fix: add an instance declaration for (Fractional Int)
In the expression: 2.3
In an equation for `y': y = 2.3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can make &lt;code&gt;x&lt;/code&gt; ambiguous with &lt;code&gt;NoMonomorphismRestriction&lt;/code&gt; option.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{-# LANGUAGE NoMonomorphismRestriction #-}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or &lt;code&gt;-XNoMonomorphismRestriction&lt;/code&gt; in command line option.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href='http://stackoverflow.com/questions/7055146/why-do-3-and-x-which-was-assigned-3-have-different-inferred-types-in-haskell'&gt;&lt;code class='url'&gt;http://stackoverflow.com/questions/7055146/why-do-3-and-x-which-was-assigned-3-have-different-inferred-types-in-haskell&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thanks @ikegami__!&lt;/p&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-7718093655869785281?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/7718093655869785281/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2011/11/type-inferences-of-ambiguous-literals.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/7718093655869785281'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/7718093655869785281'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2011/11/type-inferences-of-ambiguous-literals.html' title='Type Inferences of Ambiguous Literals'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-4533611479077376690</id><published>2011-11-03T03:25:00.001-07:00</published><updated>2011-11-03T03:29:15.296-07:00</updated><title type='text'>Lossless Data Compressions</title><content type='html'>&lt;h2 id="run-length-encoding"&gt;Run-length encoding&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Run-length_encoding"&gt;&lt;code class="url"&gt;http://en.wikipedia.org/wiki/Run-length_encoding&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;One of the easiest encoding method to write.&lt;/p&gt;
&lt;p&gt;An implementatin in Haskell:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import Data.List (group)
main = do
  print $ runlength &amp;quot;AAAAABBCBADDDDDDDD&amp;quot;

runlength = concatMap f . group
  where
    f xs@(x:_) = x : show (length xs)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;quot;A5B2C1B1A1D8&amp;quot;&lt;/p&gt;
&lt;h2 id="huffman-coding"&gt;Huffman coding&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Huffman_coding"&gt;&lt;code class="url"&gt;http://en.wikipedia.org/wiki/Huffman_coding&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;An implementatin in Haskell:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import Data.List (group, sort, sortBy)
import Data.Function (on)
import Data.Map (fromList, lookup)
import Data.Maybe (fromJust)
import Prelude hiding (lookup)

main = print $ huffman &amp;quot;AAAAABBCBADDDDDDDD&amp;quot;

huffman s = flip concatMap s $ fromJust . flip lookup (huffmanMap s)

huffmanMap s =
  let x = map head . sortBy (compare `on` length) . group . sort $ s in
      fromList $ zipWith ((,)) x (bits $ length x)
bits :: Int -&amp;gt; [[Int]]
bits length = (take length $ repeat 1) : reverse (take (length - 1) $ iterate (1 :) [0])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[1,0,1,0,1,0,1,0,1,0,1,1,0,1,1,0,1,1,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0]&lt;/p&gt;
&lt;h2 id="bpe-byte-pair-encoding"&gt;BPE: Byte Pair Encoding&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Byte_pair_encoding"&gt;&lt;code class="url"&gt;http://en.wikipedia.org/wiki/Byte_pair_encoding&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import Data.List (group, sort, sortBy, (\\))
import Data.Function (on)
import qualified Data.Map as M
import Data.Map (insert, empty, notMember)
import Data.Maybe (fromJust)
import Safe (fromJustDef)

main = do
  let orig = &amp;quot;ABCDCDABCDCDE&amp;quot;
  print orig
  let (encoded, table) = bpe orig
  print (encoded, table)
  print $ bpeDecode encoded table

bpe xs = bpe' xs empty
bpe' xs table =
  let x = head $ sortBy (flip compare `on` length) $ group $ sort $ zipWith ((,)) xs (tail xs) in
      if length x == 1
         then (xs, table)
         else let (a, b) = head x
                  new = pickupOther xs table in
                  bpe' (replace2 xs a b new) (insert new (a, b) table)

bpeDecode xs table = concatMap (replace (expand (M.map (\(a, b) -&amp;gt; [a, b]) table))) xs
  where
    replace :: M.Map Char String -&amp;gt; Char -&amp;gt; String
    replace expandedTable c = maybe [c] id $ M.lookup c expandedTable
    expand :: M.Map Char String -&amp;gt; M.Map Char String
    expand table = M.map (concatMap f) table
      where
        f :: Char -&amp;gt; String
        f c = maybe [c] (concatMap f) $ M.lookup c table

pickupOther xs table =
  head $ filter (flip notMember table) $ ['Z', 'Y'..'A'] \\ xs

replace2 (a:[]) _ _ _ = [a]
replace2 (a:b:xs) c d e
  | a == c &amp;amp;&amp;amp; b == d = e : replace2 xs c d e
  | otherwise = a : replace2 (b : xs) c d e
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&amp;quot;ABCDCDABCDCDE&amp;quot;&lt;/li&gt;
&lt;li&gt;(&amp;quot;WWE&amp;quot;,fromList [('W',('X','Z')),('X',('Y','Z')),('Y',('A','B')),('Z',('C','D'))])&lt;/li&gt;
&lt;li&gt;&amp;quot;ABCDCDABCDCDE&amp;quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-4533611479077376690?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/4533611479077376690/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2011/11/lossless-data-compressions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/4533611479077376690'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/4533611479077376690'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2011/11/lossless-data-compressions.html' title='Lossless Data Compressions'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-2527990279545869093</id><published>2011-10-31T22:44:00.001-07:00</published><updated>2011-11-01T00:36:34.916-07:00</updated><title type='text'>Optimizer Comparisons -- Skip Nops</title><content type='html'>&lt;h2 id="in-haskell"&gt;In Haskell&lt;/h2&gt;
&lt;p&gt;The following Haskell code is supposed to just output &amp;quot;hello&amp;quot;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;main = print $ times 1000000000000 id &amp;quot;hello&amp;quot;

times 0 _ x = x
times n f x = times (n-1) f (f x)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;times&lt;/code&gt; function I defined applies the given function many times.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;times 3 f x&lt;/code&gt; is...
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;times 2 f (f x)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;times 1 f (f (f x))&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;times 0 f (f (f (f x)))&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;f (f (f x))&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;id&lt;/code&gt;, defined in Prelude, just returns the given argument. You may want to assume the GHC internal optimizer to eliminate any &lt;code&gt;id&lt;/code&gt; call. In other words, the Haskell code in the very beginning is supposed to be transformed just to &lt;code&gt;main = print &amp;quot;hello&amp;quot;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Unfortunately, no it doesn't, even with &lt;code&gt;-O2&lt;/code&gt; option.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ ghc -O2 a.hs -o a
$ ./a
... (long long hours) ..
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="in-c"&gt;In C&lt;/h2&gt;
&lt;p&gt;I just translated the original Haskell code to C.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;quot;stdio.h&amp;quot;

char *id(char *x) {
  return x;
}
char *times(long long n, char *(*f)(char *), char *x) {
  if (n == 0) {
    return x;
  } else {
    return times(n-1, f, f(x));
  }
}

int main(int argc, char const* argv[]) {
  puts(times(1000000000000LL, id, &amp;quot;hello&amp;quot;));
  return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I tried it with GCC and Clang.&lt;/p&gt;
&lt;p&gt;GCC on Mac:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ gcc -O2 a.c -o a
$ ./a
... (long long hours) ..
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The assembly code for the &lt;code&gt;main&lt;/code&gt; function with &lt;code&gt;-O2 -m32&lt;/code&gt; option is the following.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;_main:
  pushl %ebp
  movl  %esp, %ebp
  pushl %ebx
  subl  $20, %esp
  call  L13
&amp;quot;L00000000001$pb&amp;quot;:
L13:
  popl  %ebx
  leal  LC0-&amp;quot;L00000000001$pb&amp;quot;(%ebx), %eax
  movl  %eax, 8(%esp)
  leal  _id-&amp;quot;L00000000001$pb&amp;quot;(%ebx), %eax
  movl  %eax, 4(%esp)
  movl  $-727379968, (%esp)
  call  _times
  movl  %eax, (%esp)
  call  _puts
  xorl  %eax, %eax
  addl  $20, %esp
  popl  %ebx
  leave
  ret
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You see it's calling &lt;code&gt;_times&lt;/code&gt; for sure.&lt;/p&gt;
&lt;p&gt;Clang:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ clang -O2 a.c -o a
$ ./a
hello
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This gives you the message immediately!&lt;/p&gt;
&lt;p&gt;The below is the generated LLVM IR. You can easily tell that it just calls &lt;code&gt;puts&lt;/code&gt; function directly. Note that the &lt;code&gt;@.str&lt;/code&gt; const is just &amp;quot;hello&amp;quot; ending with null.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;define i32 @main(i32 %argc, i8** nocapture %argv) nounwind uwtable ssp {
entry:
  %call1 = tail call i32 @puts(i8* getelementptr inbounds ([6 x i8]* @.str, i64 0, i64 0)) nounwind
  ret i32 0
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;GCC on Linux:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;gcc 4.4&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;main:
  pushl %ebp
  movl  %esp, %ebp
  andl  $-16, %esp
  subl  $16, %esp
  movl  $.LC0, (%esp)
  call  puts
  xorl  %eax, %eax
  leave
  ret
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It ran like the one with Clang!&lt;/p&gt;
&lt;h2 id="when-the-big-number-isnt-long-long"&gt;When the big number isn't long long&lt;/h2&gt;
&lt;p&gt;I wrote the first argument of &lt;code&gt;times&lt;/code&gt; in C as &lt;code&gt;int&lt;/code&gt; at first.&lt;/p&gt;
&lt;p&gt;I got warning messages from both GCC and Clang that the value, 1000000000000, was too big for int. In the case, GCC on Linux made the following assembly code.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;main:
  pushl %ebp
  movl  %esp, %ebp
.L11:
  jmp   .L11
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It's just an infinite loop! That actually makes sense because any int values never go to non-int value 1000000000000.&lt;/p&gt;
&lt;h2 id="summary"&gt;Summary&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;GHC doesn't eliminate &lt;code&gt;id&lt;/code&gt; in optimization&lt;/li&gt;
&lt;li&gt;GCC eliminates it except for Apple GCC 4.2&lt;/li&gt;
&lt;li&gt;Clang eliminates id&lt;/li&gt;
&lt;li&gt;Some optimizations can conflict if the code depends on undefined behaviour&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-2527990279545869093?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/2527990279545869093/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2011/10/optimizer-comparisons-skip-nops.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/2527990279545869093'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/2527990279545869093'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2011/10/optimizer-comparisons-skip-nops.html' title='Optimizer Comparisons -- Skip Nops'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-7509722406131357948</id><published>2011-10-30T10:33:00.001-07:00</published><updated>2011-10-30T10:33:39.667-07:00</updated><title type='text'>How To Compile C to IA32</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;Q. How to compile a C file to IA32 assembly language on AMD64 Debian?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ gcc -S -m32 a.c
In file included from /usr/include/features.h:378,
                 from /usr/include/stdio.h:28,
                 from a.c:1:
/usr/include/gnu/stubs.h:7:27: error: gnu/stubs-32.h: No such file or directory
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A. install &lt;code&gt;gcc-multilib&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo aptitude install gcc-multilib
&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-7509722406131357948?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/7509722406131357948/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2011/10/how-to-compile-c-to-ia32.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/7509722406131357948'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/7509722406131357948'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2011/10/how-to-compile-c-to-ia32.html' title='How To Compile C to IA32'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-9133001767964162441</id><published>2011-10-28T18:20:00.001-07:00</published><updated>2011-10-28T18:26:26.984-07:00</updated><title type='text'>URL Encodings</title><content type='html'>&lt;p&gt;URL Encoding, specifically Percent-encoding, is one of common encodings that you may use in arbitorary programming languages.&lt;/p&gt;
&lt;p&gt;Let me encode a text into URL Encoding, which includes UTF-8 Japanese characters.&lt;/p&gt;
&lt;h2 id="javascript-node.js"&gt;JavaScript (node.js)&lt;/h2&gt;
&lt;p&gt;Use &lt;code&gt;encodeURIComponent&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var sys = require('sys');
sys.puts(encodeURIComponent('abc あいう-#!@'));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;result:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;abc%20%E3%81%82%E3%81%84%E3%81%86-%23!%40
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that &lt;code&gt;escape&lt;/code&gt; and &lt;code&gt;encodeURI&lt;/code&gt; aren't proper for URI encoding.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sys.puts(escape('abc あいう-#!@'));
//=&amp;gt; abc%20%u3042%u3044%u3046-%23%21@
sys.puts(encodeURI('abc あいう-#!@'));
//=&amp;gt; abc%20%E3%81%82%E3%81%84%E3%81%86-#!@
sys.puts(encodeURIComponent('abc あいう-#!@'));
//=&amp;gt; abc%20%E3%81%82%E3%81%84%E3%81%86-%23!%40
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(Thanks @javascripter!)&lt;/p&gt;
&lt;h2 id="ruby"&gt;Ruby&lt;/h2&gt;
&lt;p&gt;Use &lt;code&gt;ERB::Util.url_encode&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# coding: utf-8
require 'erb'
puts ERB::Util.url_encode 'abc あいう-#!@'
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;result:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;abc%20%E3%81%82%E3%81%84%E3%81%86-%23%21%40
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This result is exactly same to JavaScript's except for &amp;quot;!&amp;quot;.&lt;/p&gt;
&lt;p&gt;Note that &lt;code&gt;URI.encode&lt;/code&gt; or &lt;code&gt;URI.encode_www_form_component&lt;/code&gt; aren't proper.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;require 'uri'
puts URI.encode 'abc あいう-#!@'
#=&amp;gt; abc%20%E3%81%82%E3%81%84%E3%81%86-%23!@
puts URI.encode_www_form_component 'abc あいう-#!@'
#=&amp;gt; abc+%E3%81%82%E3%81%84%E3%81%86-%23%21%40
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="python"&gt;Python&lt;/h2&gt;
&lt;p&gt;Use &lt;code&gt;urllib.quote&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# coding: utf-8
import urllib
print urllib.quote('abc あいう-#!@')
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;result:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;abc%20%E3%81%82%E3%81%84%E3%81%86-%23%21%40
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(Thanks @raa0121!)&lt;/p&gt;
&lt;h2 id="vim-script"&gt;Vim script&lt;/h2&gt;
&lt;p&gt;Use &lt;code&gt;Vital.Web.Http.encodeURI&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let H = vital#of('vital').import('Web.Http')
echo H.encodeURI('abc あいう-#!@')
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;result:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;abc%20%E3%81%82%E3%81%84%E3%81%86-%23%21%40
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="haskell"&gt;Haskell&lt;/h2&gt;
&lt;p&gt;Use &lt;code&gt;Network.HTTP.urlEncode&lt;/code&gt;. But...&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import Network.HTTP (urlEncode)
main = putStrLn $ urlEncode &amp;quot;abc あいう-#!@&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;result:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;abc%20%30%42%30%44%30%46-%23%21%40
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;oh...&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-9133001767964162441?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/9133001767964162441/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2011/10/url-encodings.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/9133001767964162441'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/9133001767964162441'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2011/10/url-encodings.html' title='URL Encodings'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-4009312396556132393</id><published>2011-10-25T23:27:00.001-07:00</published><updated>2011-10-26T09:24:11.827-07:00</updated><title type='text'>Converting From/To String</title><content type='html'>&lt;p&gt;Haskell has three dominant types of the implementations of strings; String, ByteString and Text(*1). Since String is the default literal of strings, most libraries only support String as strings, even though you can write ByteString or Text directly in a Haskell code with &lt;code&gt;OverloadedStrings&lt;/code&gt; pragma.&lt;/p&gt;
&lt;p&gt;Haskell has &lt;code&gt;IsString&lt;/code&gt; class that means you can convert the type to String, using &lt;code&gt;fromString&lt;/code&gt; function. &lt;code&gt;IsString&lt;/code&gt; only requires the type to have the &lt;code&gt;fromString&lt;/code&gt; function.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- in Data.String
class IsString a where
  fromString :: String -&amp;gt; a
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="tostring"&gt;ToString&lt;/h2&gt;
&lt;p&gt;I implemented &lt;code&gt;ToString&lt;/code&gt; class that you can convert from the type to String by &lt;code&gt;toString&lt;/code&gt; function, oppositely to the &lt;code&gt;IsString&lt;/code&gt; class and its &lt;code&gt;fromString&lt;/code&gt; function.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{-# LANGUAGE TypeSynonymInstances #-}
import qualified Data.Text as T
import qualified Data.ByteString.Char8 as C
import qualified Data.ByteString as B

class ToString a where
  toString :: a -&amp;gt; String

instance ToString String where
  toString = id

instance ToString T.Text where
  toString = T.unpack

instance ToString B.ByteString where
  toString = C.unpack
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can use them like the following way.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{-# LANGUAGE OverloadedStrings #-}
main = do
  putStrLn $ toString (&amp;quot;hello world!&amp;quot; :: String)
  putStrLn $ toString (&amp;quot;hello world!&amp;quot; :: T.Text)
  putStrLn $ toString (&amp;quot;hello world!&amp;quot; :: B.ByteString)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It might remind you about &lt;code&gt;show :: a -&amp;gt; String&lt;/code&gt;. &lt;code&gt;show&lt;/code&gt; and the &lt;code&gt;toString&lt;/code&gt; I defined here have the same type but the purpose and the behaviour are different. &lt;code&gt;show&lt;/code&gt; is to give human-readable and machine-parsable String represantation while &lt;code&gt;toString&lt;/code&gt; is just to convert from a type which is an implementation of the concept of strings to String.&lt;/p&gt;
&lt;p&gt;If you are familiar with Ruby, this may make sense; &lt;code&gt;show&lt;/code&gt; in Haskell is &lt;code&gt;inspect&lt;/code&gt; in Ruby while &lt;code&gt;toString&lt;/code&gt; in Haskell is &lt;code&gt;to_str&lt;/code&gt; in Ruby. Note that that's not &lt;code&gt;to_s&lt;/code&gt; whom Integer or some other non-string classes also have.&lt;/p&gt;
&lt;h2 id="use-case"&gt;Use case&lt;/h2&gt;
&lt;p&gt;An example is Network.HTTP.urlEncode function; the function is &lt;code&gt;String -&amp;gt; String&lt;/code&gt; but you may want to use it for Text values.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import qualified Data.Text as T
import qualified Network.HTTP as H
urlEncodeText :: T.Text -&amp;gt; T.Text
urlEncodeText = T.pack . H.urlEncode . T.unpack
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can define Text-specific version of &lt;code&gt;urlEncode&lt;/code&gt; easily. You can define ByteString-specific version as well in the same way. But you cannot have general one.&lt;/p&gt;
&lt;p&gt;It's turn to use the &lt;code&gt;ToString&lt;/code&gt; we saw here.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeSynonymInstances #-}
import qualified Data.Text as T
import qualified Data.Text.IO as T
import qualified Data.ByteString.Char8 as C
import qualified Data.ByteString as B
import qualified Network.HTTP as H
import Data.String (fromString, IsString)

main = do
  putStrLn $ urlEncode (&amp;quot;hello world!&amp;quot; :: String)
  T.putStrLn $ urlEncode (&amp;quot;hello world!&amp;quot; :: T.Text)
  B.putStrLn $ urlEncode (&amp;quot;hello world!&amp;quot; :: B.ByteString)

class ToString a where
  toString :: a -&amp;gt; String

instance ToString String where
  toString = id

instance ToString T.Text where
  toString = T.unpack

instance ToString B.ByteString where
  toString = C.unpack

urlEncode :: IsString a =&amp;gt; ToString a =&amp;gt; a -&amp;gt; a
urlEncode = fromString . H.urlEncode . toString
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This &lt;code&gt;urlEncode&lt;/code&gt; function defined here can use String, ByteString and Text just by the single function! I just combined IsString and ToString there :)&lt;/p&gt;
&lt;h2 id="footnote"&gt;Footnote&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;*1 see also: &lt;a href="http://www.slideshare.net/ujihisa/text-manipulation-withwithout-parsec"&gt;&lt;code class="url"&gt;http://www.slideshare.net/ujihisa/text-manipulation-withwithout-parsec&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-4009312396556132393?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/4009312396556132393/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2011/10/converting-fromto-string.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/4009312396556132393'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/4009312396556132393'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2011/10/converting-fromto-string.html' title='Converting From/To String'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-6672066367472139575</id><published>2011-10-05T22:19:00.001-07:00</published><updated>2011-10-05T22:20:10.380-07:00</updated><title type='text'>Completing Method Names in Ruby Based on Input and Output</title><content type='html'>&lt;p&gt;I described &lt;a href="http://ujihisa.blogspot.com/2011/06/vanrb-lightning-talk-slides-ruby-and.html"&gt;how to auto-complete method names of an object on Vim&lt;/a&gt; but here let me describe about a bit more restricted one. How can we auto-complete method names of an object that &lt;em&gt;goes&lt;/em&gt; to a given object?&lt;/p&gt;
&lt;p&gt;An example here that you send &lt;code&gt;succ&lt;/code&gt; or &lt;code&gt;next&lt;/code&gt; on an object 1 when you want to get an object 2.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1.succ #=&amp;gt; 2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Another example. &lt;code&gt;first&lt;/code&gt; method will let you get an object &lt;code&gt;:a&lt;/code&gt; by &lt;code&gt;[:a, :b, :c]&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[:a, :b, :c].first #=&amp;gt; :a
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is natural that you expect Vim automatically completes the method names when the cursor is on the &lt;code&gt;.&lt;/code&gt; just after the object.&lt;/p&gt;
&lt;h2 id="neco-rubymf.vim"&gt;neco-rubymf.vim&lt;/h2&gt;
&lt;p&gt;A neocomplcache plugin, &lt;a href="http://github.com/ujihisa/neco-rubymf"&gt;neco-rubymf&lt;/a&gt;, does exactly what I described above.&lt;/p&gt;
&lt;p&gt;Installation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Install a Rubygems package &lt;code&gt;methodfinder&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ gem install methodfinder
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install the neocomplcache plugin &lt;a href="http://github.com/ujihisa/neco-rubymf"&gt;neco-rubymf&lt;/a&gt;. If your Vim still don't have neocomplcache, install it as well.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Try inputting the following line in a buffer where the &lt;code&gt;'filetype'&lt;/code&gt; is &lt;code&gt;ruby&lt;/code&gt;. Note that ¶ means cursor here.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1.¶ #=&amp;gt; 2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That shows methods &lt;code&gt;next&lt;/code&gt; and &lt;code&gt;succ&lt;/code&gt; in completion popup automatically, which the method an object 1 owns and also the returning value is 2.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img src="http://cache.gyazo.com/431718249321702b98671e05463f495b.png" /&gt;&lt;p class="caption"&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Similarly,&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[:a, :b, :c].¶ #=&amp;gt; :a
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;gives this.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img src="http://cache.gyazo.com/12aab5d2e5bec7c92bf26b4eee48adee.png" /&gt;&lt;p class="caption"&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The screenshots below are other examples.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img src="http://cache.gyazo.com/73e6027c92217372f88410be049f6986.png" /&gt;&lt;p class="caption"&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="figure"&gt;
&lt;img src="http://cache.gyazo.com/e0d26e6e18d6138dd41f0e8656bfbb3f.png" /&gt;&lt;p class="caption"&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="figure"&gt;
&lt;img src="http://cache.gyazo.com/15ba0b10ba77ee74cf8fccd40332a816.png" /&gt;&lt;p class="caption"&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;※The last example occurs stochastically.&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-6672066367472139575?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/6672066367472139575/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2011/10/completing-method-names-in-ruby-based.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/6672066367472139575'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/6672066367472139575'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2011/10/completing-method-names-in-ruby-based.html' title='Completing Method Names in Ruby Based on Input and Output'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-1285934751770274092</id><published>2011-08-03T21:58:00.001-07:00</published><updated>2011-08-03T22:00:09.847-07:00</updated><title type='text'>Benchmarks between Clang and GCC about Ruby 1.9.3</title><content type='html'>&lt;p&gt;Since Matz Ruby Implimentation &lt;code&gt;ruby&lt;/code&gt; 1.9.3 has been released as preview release, I think that all Rubyists should abandon the ruby they are usually using, ruby 1.9.2, and should use 1.9.3 now.&lt;/p&gt;
&lt;p&gt;Ruby 1.9.3 also supports &lt;code&gt;clang&lt;/code&gt; instead of &lt;code&gt;gcc&lt;/code&gt; inofficially. You can compile ruby with clang 3.0 and almost everything works(*1).&lt;/p&gt;
&lt;h2 id="building-clang-3.0"&gt;Building clang 3.0&lt;/h2&gt;
&lt;p&gt;There are two things you have to understand before you build clang.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Clang is a subproject of LLVM. You cannot build clang independently to LLVM unless you are an LLVM specialist.&lt;/li&gt;
&lt;li&gt;LLVM build directly has to be not in LLVM source tree for some reason.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Otherwise it just fails building.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ mkdir -p ~/src/llvm-git-build
$ cd ~/git
$ git clone http://llvm.org/git/llvm.git
$ cd tools
$ git clone http://llvm.org/git/clang.git
$ cd ~/src/llvm-git-build
$ ~/git/llvm/configure --prefix=`pwd`/local
$ make &amp;amp;&amp;amp; make install
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That will install llvm commands and &lt;code&gt;clang&lt;/code&gt; in &lt;code&gt;~/src/llvm-git-build/local/bin&lt;/code&gt; directory.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ ~/src/llvm-git-build/local/bin/clang -v
clang version 3.0 (http://llvm.org/git/clang.git d484040a5fc8d8d8a7a6a0239fc3b34486258181)
Target: x86_64-apple-darwin10.8.0
Thread model: posix
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="building-ruby-1.9.3-with-clang"&gt;Building ruby 1.9.3 with clang&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;$ cd ~/git
$ git clone http://github.com/ruby/ruby.git ruby193
$ cd ruby193
$ git checkout ruby_1_9_3 origin/ruby_1_9_3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;a.sh&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export CC=~/src/llvm-git-build/local/bin/clang
autoconf &amp;amp;&amp;amp; ./configure --with-out-ext=tk\* --with-arch=x86_64 --prefix=`pwd`/local --with-readline-dir=/usr/local --with-libyaml-include=/usr/local/include &amp;amp;&amp;amp; make &amp;amp;&amp;amp; make install
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;then&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sh a.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="benchmark"&gt;Benchmark&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;$ local/bin/ruby benchmark/run.rb --ruby=local/bin/ruby
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I ran on &lt;code&gt;ruby&lt;/code&gt; made by clang and &lt;code&gt;ruby&lt;/code&gt; made by gcc and compared them.&lt;/p&gt;
&lt;table border="1"&gt;
&lt;thead&gt;&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;
gcc/clang
&lt;/td&gt;&lt;td&gt;
gcc [sec]
&lt;/td&gt;&lt;td&gt;
clang [sec]
&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;
loop_generator
&lt;/th&gt;&lt;td&gt;
1.55
&lt;/td&gt;&lt;td&gt;
1.187
&lt;/td&gt;&lt;td&gt;
0.768
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm_thread_pass_flood
&lt;/th&gt;&lt;td&gt;
1.38
&lt;/td&gt;&lt;td&gt;
0.52
&lt;/td&gt;&lt;td&gt;
0.377
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm1_const
&lt;/th&gt;&lt;td&gt;
1.23
&lt;/td&gt;&lt;td&gt;
1.449
&lt;/td&gt;&lt;td&gt;
1.175
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
so_random
&lt;/th&gt;&lt;td&gt;
1.15
&lt;/td&gt;&lt;td&gt;
1.191
&lt;/td&gt;&lt;td&gt;
1.04
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
so_k_nucleotide
&lt;/th&gt;&lt;td&gt;
1.11
&lt;/td&gt;&lt;td&gt;
0.02
&lt;/td&gt;&lt;td&gt;
0.018
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm2_case
&lt;/th&gt;&lt;td&gt;
1.10
&lt;/td&gt;&lt;td&gt;
0.338
&lt;/td&gt;&lt;td&gt;
0.307
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm2_regexp
&lt;/th&gt;&lt;td&gt;
1.07
&lt;/td&gt;&lt;td&gt;
1.8
&lt;/td&gt;&lt;td&gt;
1.683
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
loop_whileloop
&lt;/th&gt;&lt;td&gt;
1.07
&lt;/td&gt;&lt;td&gt;
0.677
&lt;/td&gt;&lt;td&gt;
0.634
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm_thread_pipe
&lt;/th&gt;&lt;td&gt;
1.07
&lt;/td&gt;&lt;td&gt;
1.659
&lt;/td&gt;&lt;td&gt;
1.556
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
so_count_words
&lt;/th&gt;&lt;td&gt;
1.06
&lt;/td&gt;&lt;td&gt;
0.442
&lt;/td&gt;&lt;td&gt;
0.418
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
loop_whileloop2
&lt;/th&gt;&lt;td&gt;
1.06
&lt;/td&gt;&lt;td&gt;
0.148
&lt;/td&gt;&lt;td&gt;
0.14
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
so_reverse_complement
&lt;/th&gt;&lt;td&gt;
1.06
&lt;/td&gt;&lt;td&gt;
0.019
&lt;/td&gt;&lt;td&gt;
0.018
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm1_swap
&lt;/th&gt;&lt;td&gt;
1.06
&lt;/td&gt;&lt;td&gt;
0.956
&lt;/td&gt;&lt;td&gt;
0.906
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm2_array
&lt;/th&gt;&lt;td&gt;
1.05
&lt;/td&gt;&lt;td&gt;
1.543
&lt;/td&gt;&lt;td&gt;
1.468
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm1_ivar
&lt;/th&gt;&lt;td&gt;
1.04
&lt;/td&gt;&lt;td&gt;
1.662
&lt;/td&gt;&lt;td&gt;
1.596
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm1_length
&lt;/th&gt;&lt;td&gt;
1.04
&lt;/td&gt;&lt;td&gt;
1.467
&lt;/td&gt;&lt;td&gt;
1.412
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm_thread_create_join
&lt;/th&gt;&lt;td&gt;
1.03
&lt;/td&gt;&lt;td&gt;
4.45
&lt;/td&gt;&lt;td&gt;
4.321
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm_thread_pass
&lt;/th&gt;&lt;td&gt;
1.02
&lt;/td&gt;&lt;td&gt;
2.308
&lt;/td&gt;&lt;td&gt;
2.258
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
loop_times
&lt;/th&gt;&lt;td&gt;
1.02
&lt;/td&gt;&lt;td&gt;
1.834
&lt;/td&gt;&lt;td&gt;
1.796
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
app_uri
&lt;/th&gt;&lt;td&gt;
1.01
&lt;/td&gt;&lt;td&gt;
1.362
&lt;/td&gt;&lt;td&gt;
1.346
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
io_select2
&lt;/th&gt;&lt;td&gt;
1.00
&lt;/td&gt;&lt;td&gt;
3.976
&lt;/td&gt;&lt;td&gt;
3.957
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm1_rescue
&lt;/th&gt;&lt;td&gt;
1.00
&lt;/td&gt;&lt;td&gt;
0.799
&lt;/td&gt;&lt;td&gt;
0.798
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm1_ivar_set
&lt;/th&gt;&lt;td&gt;
1.00
&lt;/td&gt;&lt;td&gt;
1.766
&lt;/td&gt;&lt;td&gt;
1.765
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
io_select3
&lt;/th&gt;&lt;td&gt;
1.00
&lt;/td&gt;&lt;td&gt;
0.03
&lt;/td&gt;&lt;td&gt;
0.03
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm1_ensure
&lt;/th&gt;&lt;td&gt;
1.00
&lt;/td&gt;&lt;td&gt;
0.736
&lt;/td&gt;&lt;td&gt;
0.738
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
io_select
&lt;/th&gt;&lt;td&gt;
1.00
&lt;/td&gt;&lt;td&gt;
3.503
&lt;/td&gt;&lt;td&gt;
3.513
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm_thread_alive_check1
&lt;/th&gt;&lt;td&gt;
1.00
&lt;/td&gt;&lt;td&gt;
0.327
&lt;/td&gt;&lt;td&gt;
0.328
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
so_mandelbrot
&lt;/th&gt;&lt;td&gt;
0.99
&lt;/td&gt;&lt;td&gt;
6.776
&lt;/td&gt;&lt;td&gt;
6.817
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm1_not
&lt;/th&gt;&lt;td&gt;
0.99
&lt;/td&gt;&lt;td&gt;
0.958
&lt;/td&gt;&lt;td&gt;
0.965
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm2_poly_method_ov
&lt;/th&gt;&lt;td&gt;
0.98
&lt;/td&gt;&lt;td&gt;
0.422
&lt;/td&gt;&lt;td&gt;
0.43
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
io_file_write
&lt;/th&gt;&lt;td&gt;
0.98
&lt;/td&gt;&lt;td&gt;
1.78
&lt;/td&gt;&lt;td&gt;
1.815
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
so_nbody
&lt;/th&gt;&lt;td&gt;
0.97
&lt;/td&gt;&lt;td&gt;
4.861
&lt;/td&gt;&lt;td&gt;
5.012
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm2_eval
&lt;/th&gt;&lt;td&gt;
0.97
&lt;/td&gt;&lt;td&gt;
28.817
&lt;/td&gt;&lt;td&gt;
29.772
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
so_partial_sums
&lt;/th&gt;&lt;td&gt;
0.97
&lt;/td&gt;&lt;td&gt;
6.003
&lt;/td&gt;&lt;td&gt;
6.211
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
so_concatenate
&lt;/th&gt;&lt;td&gt;
0.96
&lt;/td&gt;&lt;td&gt;
5.322
&lt;/td&gt;&lt;td&gt;
5.536
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
so_exception
&lt;/th&gt;&lt;td&gt;
0.96
&lt;/td&gt;&lt;td&gt;
1.653
&lt;/td&gt;&lt;td&gt;
1.723
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
loop_for
&lt;/th&gt;&lt;td&gt;
0.95
&lt;/td&gt;&lt;td&gt;
1.865
&lt;/td&gt;&lt;td&gt;
1.96
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm1_neq
&lt;/th&gt;&lt;td&gt;
0.95
&lt;/td&gt;&lt;td&gt;
1.206
&lt;/td&gt;&lt;td&gt;
1.269
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
io_file_read
&lt;/th&gt;&lt;td&gt;
0.95
&lt;/td&gt;&lt;td&gt;
3.764
&lt;/td&gt;&lt;td&gt;
3.965
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
so_sieve
&lt;/th&gt;&lt;td&gt;
0.94
&lt;/td&gt;&lt;td&gt;
1.06
&lt;/td&gt;&lt;td&gt;
1.13
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm3_gc
&lt;/th&gt;&lt;td&gt;
0.93
&lt;/td&gt;&lt;td&gt;
1.593
&lt;/td&gt;&lt;td&gt;
1.712
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
so_pidigits
&lt;/th&gt;&lt;td&gt;
0.92
&lt;/td&gt;&lt;td&gt;
0.905
&lt;/td&gt;&lt;td&gt;
0.982
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
so_spectralnorm
&lt;/th&gt;&lt;td&gt;
0.92
&lt;/td&gt;&lt;td&gt;
3.911
&lt;/td&gt;&lt;td&gt;
4.265
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm2_proc
&lt;/th&gt;&lt;td&gt;
0.91
&lt;/td&gt;&lt;td&gt;
0.858
&lt;/td&gt;&lt;td&gt;
0.941
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
so_nested_loop
&lt;/th&gt;&lt;td&gt;
0.91
&lt;/td&gt;&lt;td&gt;
1.415
&lt;/td&gt;&lt;td&gt;
1.554
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
so_fannkuch
&lt;/th&gt;&lt;td&gt;
0.89
&lt;/td&gt;&lt;td&gt;
2.321
&lt;/td&gt;&lt;td&gt;
2.6
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm3_clearmethodcache
&lt;/th&gt;&lt;td&gt;
0.89
&lt;/td&gt;&lt;td&gt;
0.683
&lt;/td&gt;&lt;td&gt;
0.767
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
so_array
&lt;/th&gt;&lt;td&gt;
0.89
&lt;/td&gt;&lt;td&gt;
1.859
&lt;/td&gt;&lt;td&gt;
2.098
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm2_defined_method
&lt;/th&gt;&lt;td&gt;
0.88
&lt;/td&gt;&lt;td&gt;
4.449
&lt;/td&gt;&lt;td&gt;
5.034
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
io_file_create
&lt;/th&gt;&lt;td&gt;
0.88
&lt;/td&gt;&lt;td&gt;
4.266
&lt;/td&gt;&lt;td&gt;
4.831
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm1_simplereturn
&lt;/th&gt;&lt;td&gt;
0.88
&lt;/td&gt;&lt;td&gt;
2.034
&lt;/td&gt;&lt;td&gt;
2.307
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm_thread_mutex3
&lt;/th&gt;&lt;td&gt;
0.88
&lt;/td&gt;&lt;td&gt;
1.894
&lt;/td&gt;&lt;td&gt;
2.164
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm2_send
&lt;/th&gt;&lt;td&gt;
0.87
&lt;/td&gt;&lt;td&gt;
0.494
&lt;/td&gt;&lt;td&gt;
0.567
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm2_unif1
&lt;/th&gt;&lt;td&gt;
0.87
&lt;/td&gt;&lt;td&gt;
0.419
&lt;/td&gt;&lt;td&gt;
0.484
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
so_matrix
&lt;/th&gt;&lt;td&gt;
0.86
&lt;/td&gt;&lt;td&gt;
1.173
&lt;/td&gt;&lt;td&gt;
1.357
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
so_nsieve_bits
&lt;/th&gt;&lt;td&gt;
0.86
&lt;/td&gt;&lt;td&gt;
4.002
&lt;/td&gt;&lt;td&gt;
4.637
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
app_tak
&lt;/th&gt;&lt;td&gt;
0.86
&lt;/td&gt;&lt;td&gt;
1.133
&lt;/td&gt;&lt;td&gt;
1.316
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
so_lists
&lt;/th&gt;&lt;td&gt;
0.85
&lt;/td&gt;&lt;td&gt;
1.439
&lt;/td&gt;&lt;td&gt;
1.698
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
app_tarai
&lt;/th&gt;&lt;td&gt;
0.85
&lt;/td&gt;&lt;td&gt;
0.9
&lt;/td&gt;&lt;td&gt;
1.062
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm1_block
&lt;/th&gt;&lt;td&gt;
0.85
&lt;/td&gt;&lt;td&gt;
2.818
&lt;/td&gt;&lt;td&gt;
3.331
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
so_ackermann
&lt;/th&gt;&lt;td&gt;
0.82
&lt;/td&gt;&lt;td&gt;
0.891
&lt;/td&gt;&lt;td&gt;
1.082
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm_thread_mutex1
&lt;/th&gt;&lt;td&gt;
0.82
&lt;/td&gt;&lt;td&gt;
1.145
&lt;/td&gt;&lt;td&gt;
1.393
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
so_nsieve
&lt;/th&gt;&lt;td&gt;
0.80
&lt;/td&gt;&lt;td&gt;
3.188
&lt;/td&gt;&lt;td&gt;
3.967
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm2_super
&lt;/th&gt;&lt;td&gt;
0.80
&lt;/td&gt;&lt;td&gt;
0.68
&lt;/td&gt;&lt;td&gt;
0.852
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
so_binary_trees
&lt;/th&gt;&lt;td&gt;
0.79
&lt;/td&gt;&lt;td&gt;
0.492
&lt;/td&gt;&lt;td&gt;
0.62
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
app_strconcat
&lt;/th&gt;&lt;td&gt;
0.79
&lt;/td&gt;&lt;td&gt;
1.93
&lt;/td&gt;&lt;td&gt;
2.444
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm2_mutex
&lt;/th&gt;&lt;td&gt;
0.79
&lt;/td&gt;&lt;td&gt;
1.546
&lt;/td&gt;&lt;td&gt;
1.968
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm2_zsuper
&lt;/th&gt;&lt;td&gt;
0.78
&lt;/td&gt;&lt;td&gt;
0.682
&lt;/td&gt;&lt;td&gt;
0.88
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm2_poly_method
&lt;/th&gt;&lt;td&gt;
0.77
&lt;/td&gt;&lt;td&gt;
2.654
&lt;/td&gt;&lt;td&gt;
3.444
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
app_factorial
&lt;/th&gt;&lt;td&gt;
0.76
&lt;/td&gt;&lt;td&gt;
1.317
&lt;/td&gt;&lt;td&gt;
1.734
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
app_erb
&lt;/th&gt;&lt;td&gt;
0.76
&lt;/td&gt;&lt;td&gt;
1.834
&lt;/td&gt;&lt;td&gt;
2.426
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
so_meteor_contest
&lt;/th&gt;&lt;td&gt;
0.75
&lt;/td&gt;&lt;td&gt;
4.953
&lt;/td&gt;&lt;td&gt;
6.626
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
so_object
&lt;/th&gt;&lt;td&gt;
0.74
&lt;/td&gt;&lt;td&gt;
1.047
&lt;/td&gt;&lt;td&gt;
1.416
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm2_method
&lt;/th&gt;&lt;td&gt;
0.71
&lt;/td&gt;&lt;td&gt;
2.174
&lt;/td&gt;&lt;td&gt;
3.049
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
app_pentomino
&lt;/th&gt;&lt;td&gt;
0.70
&lt;/td&gt;&lt;td&gt;
25.525
&lt;/td&gt;&lt;td&gt;
36.325
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
app_fib
&lt;/th&gt;&lt;td&gt;
0.70
&lt;/td&gt;&lt;td&gt;
0.812
&lt;/td&gt;&lt;td&gt;
1.168
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
so_fasta
&lt;/th&gt;&lt;td&gt;
0.67
&lt;/td&gt;&lt;td&gt;
2.866
&lt;/td&gt;&lt;td&gt;
4.302
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
app_answer
&lt;/th&gt;&lt;td&gt;
0.66
&lt;/td&gt;&lt;td&gt;
0.075
&lt;/td&gt;&lt;td&gt;
0.113
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
app_mandelbrot
&lt;/th&gt;&lt;td&gt;
0.65
&lt;/td&gt;&lt;td&gt;
2.422
&lt;/td&gt;&lt;td&gt;
3.743
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
app_raise
&lt;/th&gt;&lt;td&gt;
0.49
&lt;/td&gt;&lt;td&gt;
0.861
&lt;/td&gt;&lt;td&gt;
1.743
&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;
vm_thread_mutex2
&lt;/th&gt;&lt;td&gt;
0.41
&lt;/td&gt;&lt;td&gt;
1.228
&lt;/td&gt;&lt;td&gt;
2.977
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Considering all the results gcc-made ruby is faster than clang-made ruby but not in all the benchmarks. Hopefully the results must be an interesting example for some people.&lt;/p&gt;
&lt;h2 id="footnote-and-references"&gt;Footnote and references&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;*1: &lt;code&gt;make test-all&lt;/code&gt; shows that there is one issue in Fiber with the ruby made by clang.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://ujihisa.blogspot.com/2011/01/how-to-build-mri-n-times-faster.html"&gt;&lt;code class="url"&gt;http://ujihisa.blogspot.com/2011/01/how-to-build-mri-n-times-faster.html&lt;/code&gt;&lt;/a&gt; comparison between clang and gcc about time to build ruby&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-1285934751770274092?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/1285934751770274092/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2011/08/benchmarks-between-clang-and-gcc-about.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/1285934751770274092'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/1285934751770274092'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2011/08/benchmarks-between-clang-and-gcc-about.html' title='Benchmarks between Clang and GCC about Ruby 1.9.3'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-150193201853511765</id><published>2011-07-25T21:14:00.001-07:00</published><updated>2011-07-25T21:14:00.273-07:00</updated><title type='text'>Compiling a C File, Preserving the LLVM File</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;Assuming you have a C file &lt;code&gt;a.c&lt;/code&gt; and want to get &lt;code&gt;a.ll&lt;/code&gt; and &lt;code&gt;a.o&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;An intuitive way is that&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ clang -flto -S a.c
$ mv a.s a.ll
$ clang -flto -c a.c
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But the second &lt;code&gt;clang&lt;/code&gt; looks waste of CPU; you generate an LLVM assembly language and then you generate an object file through LLVM assembly language without using the generated assembly file.&lt;/p&gt;
&lt;p&gt;Let me break down the second command into small pieces..&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ clang -flto -S a.c
$ mv a.s a.ll
$ llc a.ll
$ gcc -c a.s
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id='in-gcc'&gt;In GCC&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;$ gcc -c --save-temps a.c
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;oh... very easy...&lt;/p&gt;
&lt;p&gt;&lt;a href='http://www.qiita.com/questions/87'&gt;&lt;code class='url'&gt;http://www.qiita.com/questions/87&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-150193201853511765?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/150193201853511765/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2011/07/compiling-c-file-preserving-llvm-file.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/150193201853511765'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/150193201853511765'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2011/07/compiling-c-file-preserving-llvm-file.html' title='Compiling a C File, Preserving the LLVM File'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-6459395674387667500</id><published>2011-07-23T14:18:00.001-07:00</published><updated>2011-07-23T14:18:50.395-07:00</updated><title type='text'>String Interpolation in Haskell</title><content type='html'>&lt;p&gt;Ruby has a special syntac in String literal which name is String Interpolation that you can write the result of a expression in a string easily.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;quot;hello, #{name}!&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The notation is equivalent to the following notation.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;quot;hello, &amp;quot; + name + &amp;quot;!&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That's not only available in Ruby but also in CoffeeScript.&lt;/p&gt;
&lt;p&gt;I wrote this for Haskell in Haskell.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{-# LANGUAGE OverloadedStrings #-}
import qualified Data.Text as T
import qualified Data.Text.IO as T
import qualified Data.Attoparsec.Text as P
import Control.Applicative

main = T.putStrLn $ stringInterpolate &amp;quot;as{df \&amp;quot;jkl#{x}jkw\&amp;quot;jl}kf&amp;quot;

(&amp;lt;&amp;lt;) = T.append

stringInterpolate :: T.Text -&amp;gt; T.Text
stringInterpolate x = case P.parseOnly stringInterpolate' x of
                           Left x -&amp;gt; T.pack x
                           Right x -&amp;gt; x

stringInterpolate' :: P.Parser T.Text
stringInterpolate' = P.try $
  T.concat &amp;lt;$&amp;gt; P.many (block &amp;lt;|&amp;gt; string &amp;lt;|&amp;gt; T.singleton `fmap` P.notChar '}')

block :: P.Parser T.Text
block = P.try $ do
  x &amp;lt;- (P.char '{') *&amp;gt; stringInterpolate' &amp;lt;* (P.char '}')
  return $ &amp;quot;{&amp;quot; &amp;lt;&amp;lt; x &amp;lt;&amp;lt; &amp;quot;}&amp;quot;

-- &amp;quot;jklsfj#{...}sdjfkl&amp;quot;
string :: P.Parser T.Text
string = P.try $ do
  x &amp;lt;- (P.char '&amp;quot;') *&amp;gt; stringContent &amp;lt;* (P.char '&amp;quot;')
  return $ &amp;quot;(\&amp;quot;&amp;quot; &amp;lt;&amp;lt; x &amp;lt;&amp;lt; &amp;quot;\&amp;quot;)&amp;quot;

-- jklsfj#{...}sdjfkl
stringContent :: P.Parser T.Text
stringContent = P.try $
  T.concat &amp;lt;$&amp;gt; P.many (interpolate &amp;lt;|&amp;gt; T.singleton `fmap` P.notChar '&amp;quot;')

-- #{...}
interpolate :: P.Parser T.Text
interpolate = P.try $ do
  x &amp;lt;- P.string &amp;quot;#{&amp;quot; *&amp;gt; stringInterpolate' &amp;lt;* P.char '}'
  return $ &amp;quot;\&amp;quot; ++ &amp;quot; &amp;lt;&amp;lt; x &amp;lt;&amp;lt; &amp;quot; ++ \&amp;quot;&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;String concatination in Haskell is &lt;code&gt;++&lt;/code&gt;. The program above converts string literals like the below.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;quot;hello, #{name}!&amp;quot;

(&amp;quot;hello, &amp;quot; ++ name ++ &amp;quot;!&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can write arbitrary expression in the placeholder.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;quot;hello, #{[ toUpper c | c &amp;lt;- ['a'..'z'] ]}!&amp;quot;

(&amp;quot;hello, &amp;quot; ++ [ toUpper c | c &amp;lt;- ['a'..'z'] ] ++ &amp;quot;!&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-6459395674387667500?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/6459395674387667500/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2011/07/string-interpolation-in-haskell.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/6459395674387667500'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/6459395674387667500'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2011/07/string-interpolation-in-haskell.html' title='String Interpolation in Haskell'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-6400639395301725933</id><published>2011-06-30T19:39:00.001-07:00</published><updated>2011-06-30T20:13:41.670-07:00</updated><title type='text'>Vanrb Lightning Talk Slides: Ruby and Vim</title><content type='html'>&lt;p&gt;&lt;a href="http://www.meetup.com/vancouver-ruby-rails/events/21277581/"&gt;&lt;code class="url"&gt;http://www.meetup.com/vancouver-ruby-rails/events/21277581/&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img src="http://gyazo.com/4b006597661aa7f4fb74109c1a94a704.png" alt="structure" /&gt;&lt;p class="caption"&gt;structure&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="rsense"&gt;RSense&lt;/h2&gt;
&lt;p&gt;A Ruby development toolset&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Code completion&lt;/li&gt;
&lt;li&gt;Type inspection&lt;/li&gt;
&lt;li&gt;Definition jump&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="rsense-code-completion"&gt;RSense code completion&lt;/h2&gt;
&lt;p&gt;a.rb&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;a = '123'
b = a.to_i
b.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;rsense command&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ rsense code-completion --file=a.rb --location=3:2
completion: to_enum Object#to_enum Object METHOD
completion: succ! String#succ! String METHOD
completion: swapcase! String#swapcase! String METHOD
completion: instance_variable_defined? Object#instance_variable_defined? Object METHOD
...
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="implementation"&gt;Implementation&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Front-end command bin/rsense&lt;/li&gt;
&lt;li&gt;Back-end server process with Java&amp;amp;JRuby&lt;/li&gt;
&lt;li&gt;Type-inference algorithm &amp;quot;modified-Cartesian Product Algorithm&amp;quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="limitations"&gt;limitations&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;classes in the buffer&lt;/li&gt;
&lt;li&gt;1.8 built-in libraries&lt;/li&gt;
&lt;li&gt;incorrect syntax&lt;/li&gt;
&lt;li&gt;evals and exceptions&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="vim"&gt;Vim&lt;/h2&gt;
&lt;div class="figure"&gt;
&lt;img src="http://www.kk.org/cooltools/venturing_into_vim.jpeg" alt="Vim" /&gt;&lt;p class="caption"&gt;Vim&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="vim-and-me"&gt;Vim and me&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;fullscreen MacVim&lt;/li&gt;
&lt;li&gt;vimshell (no other terminals)&lt;/li&gt;
&lt;li&gt;neocomplcache&lt;/li&gt;
&lt;li&gt;unite&lt;/li&gt;
&lt;li&gt;quickrun&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="rsense-built-in-vim-plugin"&gt;RSense built-in Vim plugin&lt;/h2&gt;
&lt;p&gt;User-defined completion &lt;code&gt;&amp;lt;C-x&amp;gt;&amp;lt;C-u&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;a = '123'
b = a.to_i
b._
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="insert-mode-completions-in-general"&gt;Insert-mode completions in general&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;C-n&amp;gt;&lt;/code&gt; Keyword&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;C-x&amp;gt;&amp;lt;C-f&amp;gt;&lt;/code&gt; File name&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;C-x&amp;gt;&amp;lt;C-s&amp;gt;&lt;/code&gt; English spelling&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;C-x&amp;gt;&amp;lt;C-o&amp;gt;&lt;/code&gt; Omni&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;C-x&amp;gt;&amp;lt;C-u&amp;gt;&lt;/code&gt; User-defined&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="neocomplcache"&gt;neocomplcache&lt;/h2&gt;
&lt;p&gt;Insert-mode auto-completion plugin framework&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No key mapping necessary&lt;/li&gt;
&lt;li&gt;Integrates lots of completions&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="rsense-as-omni-func"&gt;RSense as omni func&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;~/.vimrc&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let g:rsenseUseOmniFunc = 1
let g:rsenseHome = expand('~/git/rsense')

let g:neocomplcache_omni_patterns = {}
let g:neocomplcache_omni_patterns.ruby = '[^. *\t]\.\w*\|\h\w*::'
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="one-more-thing"&gt;one more thing&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;neco-&lt;/code&gt;: prefix for neocomplcache plugins&lt;/li&gt;
&lt;li&gt;neco-rake: rake task completion&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="section"&gt;&lt;/h2&gt;
&lt;div class="figure"&gt;
&lt;img src="http://gyazo.com/4b006597661aa7f4fb74109c1a94a704.png" alt="structure" /&gt;&lt;p class="caption"&gt;structure&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://ujihisa.blogspot.com"&gt;&lt;code class="url"&gt;http://ujihisa.blogspot.com&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://twitter.com/ujm"&gt;&lt;code class="url"&gt;http://twitter.com/ujm&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;google &lt;code&gt;rsense&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;google &lt;code&gt;neocomplcache&lt;/code&gt; if you are a Vimmer&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-6400639395301725933?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/6400639395301725933/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2011/06/vanrb-lightning-talk-slides-ruby-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/6400639395301725933'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/6400639395301725933'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2011/06/vanrb-lightning-talk-slides-ruby-and.html' title='Vanrb Lightning Talk Slides: Ruby and Vim'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-2389261708941574822</id><published>2011-06-12T00:57:00.001-07:00</published><updated>2011-06-12T12:55:53.239-07:00</updated><title type='text'>String#slice of Ruby in Vim script and Haskell</title><content type='html'>&lt;p&gt;A Ruby example of &lt;code&gt;String#[]&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;str = &amp;quot;Oh, this is a pen.&amp;quot;
p str[/this is a (\w+)\./, 1]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The result is &amp;quot;pen&amp;quot;. Since &lt;code&gt;String#[]&lt;/code&gt; is just an alias of &lt;code&gt;String#slice&lt;/code&gt;, (*1)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;p str.slice(/this is a (\w+)\./, 1)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The result is completely same.&lt;/p&gt;
&lt;h2 id="in-vim-script"&gt;in Vim script&lt;/h2&gt;
&lt;p&gt;Vim script version needs two separate processes; getting the list of first-matched string itself and containing sub matches, and then getting the specific item.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let str = &amp;quot;Oh, this is a pen.&amp;quot;
echo matchlist(str, 'this is a \(\w\+\)\.')[1]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;(Added at Sun Jun 12 09:26:44 PDT 2011)&lt;/em&gt; &lt;a href="http://twitter.com/thinca"&gt;thinca&lt;/a&gt; suggested that &lt;code&gt;matchstr()&lt;/code&gt; with &lt;code&gt;\zs&lt;/code&gt; and &lt;code&gt;\ze&lt;/code&gt; is very handy, particularly because of the different behavior in the case when it didn't match.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let str = &amp;quot;Oh, this is a pen.&amp;quot;
echo matchstr(str, 'this is a \zs\w\+\ze\.')
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="in-haskell"&gt;in Haskell&lt;/h2&gt;
&lt;p&gt;Haskell version needs three separate processes with &lt;code&gt;Text.Regex.Posix.=~&lt;/code&gt;; it's almost same to Vim but the default &lt;code&gt;=~&lt;/code&gt; behaviour is to assume the regex object has &amp;quot;global&amp;quot; option, so you have to pick which match.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import Text.Regex.Posix ((=~))
main = do
  let str = &amp;quot;Oh this is a pen.&amp;quot;
  print $ head (str =~ &amp;quot;this is a ([a-zA-Z_]*)&amp;quot; :: [[String]]) !! 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;(Added at Sun Jun 12 12:54:01 PDT 2011)&lt;/em&gt; The following code is another example; it's safe in runtime and also this supports Vim's &lt;code&gt;\zs&lt;/code&gt; and &lt;code&gt;\ze&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import Text.Regex.PCRE ((=~))
import Data.String.Utils (replace)
import Safe (headMay, atMay)
import Data.Maybe (fromMaybe)

matchstr :: String -&amp;gt; String -&amp;gt; String
matchstr expr pat =
  let x = replace &amp;quot;\\zs&amp;quot; &amp;quot;(&amp;quot; $ replace &amp;quot;\\ze&amp;quot; &amp;quot;)&amp;quot; pat in
  fromMaybe &amp;quot;&amp;quot; $ headMay (expr =~ x :: [[String]]) &amp;gt;&amp;gt;= \y -&amp;gt; atMay y 1

main = print $ matchstr &amp;quot;this is a pen&amp;quot; &amp;quot; \\zs\\w+\\ze&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;(*1) Precisely no. Try and check the differences between them without the second argument.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-2389261708941574822?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/2389261708941574822/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2011/06/stringslice-of-ruby-in-vim-script-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/2389261708941574822'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/2389261708941574822'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2011/06/stringslice-of-ruby-in-vim-script-and.html' title='String#slice of Ruby in Vim script and Haskell'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-5965733088140670780</id><published>2011-05-31T21:17:00.001-07:00</published><updated>2011-05-31T21:18:22.173-07:00</updated><title type='text'>A Vim Workshop in Tokyo, Japan in May</title><content type='html'>&lt;p
&gt;I organized a Vim workshop in Tokyo, Japan. The name of the workshop was &lt;a href="http://cotocoto.jp/event/45772"
  &gt;ujihisa.vim&lt;/a
  &gt;. More than 40 people tried to come but 20+ people attended at this workshop due to the capacity of the room.&lt;/p
&gt;&lt;div class="figure"
&gt;&lt;img src="http://cache.gyazo.com/b4bf192e9a73b43c1946c4aed9a760fd.png"
   /&gt;&lt;p class="caption"
  &gt;&lt;/p
  &gt;&lt;/div
&gt;&lt;h2 id="the-venue"
&gt;The venue&lt;/h2
&gt;&lt;p
&gt;I went to Tokyo for this workshop.&lt;/p
&gt;&lt;div class="figure"
&gt;&lt;img src="http://farm6.static.flickr.com/5269/5760569281_3dd19652df_z.jpg"
   /&gt;&lt;p class="caption"
  &gt;&lt;/p
  &gt;&lt;/div
&gt;&lt;div class="figure"
&gt;&lt;img src="http://cdn-ak.f.st-hatena.com/images/fotolife/g/guyon/20110514/20110514162014.jpg" alt="a photo by guyon"
   /&gt;&lt;p class="caption"
  &gt;a photo by guyon&lt;/p
  &gt;&lt;/div
&gt;&lt;p
&gt;Thanks &lt;a href="http://www.timedia.co.jp/"
  &gt;TMI&lt;/a
  &gt; and &lt;a href="http://twitter.com/kana1"
  &gt;kana1&lt;/a
  &gt;!&lt;/p
&gt;&lt;h2 id="talks"
&gt;Talks&lt;/h2
&gt;&lt;ol style="list-style-type: decimal;"
&gt;&lt;li
  &gt;&lt;em
    &gt;shadow.vim&lt;/em
    &gt; with me&lt;ul
    &gt;&lt;li
      &gt;shadow.vim &lt;a href="https://github.com/ujihisa/shadow.vim"
	&gt;&lt;code
	  &gt;https://github.com/ujihisa/shadow.vim&lt;/code
	  &gt;&lt;/a
	&gt;&lt;/li
      &gt;&lt;li
      &gt;arbitrary macros for arbitrary programming languages&lt;/li
      &gt;&lt;li
      &gt;e.g. compiling CoffeeScript into JavaScript secretly&lt;/li
      &gt;&lt;li
      &gt;it's not a framework but just a tool; you can combine it with others easily&lt;/li
      &gt;&lt;li
      &gt;shadow.el is also available &lt;a href="https://github.com/mooz/shadow.el"
	&gt;&lt;code
	  &gt;https://github.com/mooz/shadow.el&lt;/code
	  &gt;&lt;/a
	&gt;&lt;/li
      &gt;&lt;/ul
    &gt;&lt;/li
  &gt;&lt;li
  &gt;&lt;em
    &gt;all your vimrc is belong to us&lt;/em
    &gt; with &lt;a href="http://twitter.com/kana1"
    &gt;kana1&lt;/a
    &gt;&lt;ul
    &gt;&lt;li
      &gt;picks a victim, points a lot of bad smells in the vimrc of the victim, and fix them!&lt;/li
      &gt;&lt;li
      &gt;if the length of your vimrc is less than 1000, you aren't a Vimmer yet.&lt;/li
      &gt;&lt;li
      &gt;&lt;code
	&gt;syntax on&lt;/code
	&gt; is evil. use &lt;code
	&gt;syntax enable&lt;/code
	&gt;.&lt;/li
      &gt;&lt;/ul
    &gt;&lt;/li
  &gt;&lt;li
  &gt;&lt;em
    &gt;i18n&lt;/em
    &gt; with &lt;a href="http://twitter.com/niw"
    &gt;niw&lt;/a
    &gt;&lt;ul
    &gt;&lt;li
      &gt;&lt;code
	&gt;strchars()&lt;/code
	&gt; doesn't treat multi-byte character correctly.&lt;/li
      &gt;&lt;/ul
    &gt;&lt;/li
  &gt;&lt;li
  &gt;&lt;em
    &gt;tiny-vim&lt;/em
    &gt; with &lt;a href="http://twitter.com/gu4"
    &gt;guyon&lt;/a
    &gt;&lt;ul
    &gt;&lt;li
      &gt;about Debian package &amp;quot;tiny-vim&amp;quot;&lt;/li
      &gt;&lt;li
      &gt;no built-in documentation!&lt;/li
      &gt;&lt;/ul
    &gt;&lt;/li
  &gt;&lt;li
  &gt;&lt;em
    &gt;Vim in 5 minutes&lt;/em
    &gt; with &lt;a href="http://twitter.com/ShougoMatsu"
    &gt;Shougo&lt;/a
    &gt;&lt;ul
    &gt;&lt;li
      &gt;neocomplcache, unite, vimshell and vimfiler author&lt;/li
      &gt;&lt;li
      &gt;explained everything about Vim exactly within 5 minutes and extra minutes for further details&lt;/li
      &gt;&lt;/ul
    &gt;&lt;/li
  &gt;&lt;li
  &gt;&lt;em
    &gt;vital.vim&lt;/em
    &gt; with me&lt;ul
    &gt;&lt;li
      &gt;it's amazing. use it if you are a Vim plugin author.&lt;/li
      &gt;&lt;li
      &gt;something like jQuery (from JavaScript) + Bundler (from Ruby)&lt;/li
      &gt;&lt;li
      &gt;there's an issue in vital.vim about debugging with quickrun. (*)&lt;/li
      &gt;&lt;/ul
    &gt;&lt;/li
  &gt;&lt;li
  &gt;&lt;em
    &gt;metarw-yakiudon&lt;/em
    &gt; with &lt;a href="http://twitter.com/sora_h"
    &gt;sora_h&lt;/a
    &gt;&lt;ul
    &gt;&lt;li
      &gt;a metarw plugin yakiudon&lt;/li
      &gt;&lt;li
      &gt;works almost exactly same as &lt;a href="https://github.com/ujihisa/blogger.vim"
	&gt;blogger.vim&lt;/a
	&gt; but the backend Ruby library is different&lt;/li
      &gt;&lt;li
      &gt;after this presentation he talked about Ruby core development&lt;/li
      &gt;&lt;/ul
    &gt;&lt;/li
  &gt;&lt;/ol
&gt;&lt;p
&gt;(*) &lt;a href="http://twitter.com/thinca"
  &gt;thinca&lt;/a
  &gt;, the quickrun author, fixed this issue with the following &lt;a href="https://github.com/ujihisa/vital.vim/commit/0299f0f0de21e750eecd844977f00f9eefa62efd"
  &gt;change in vital&lt;/a
  &gt; during the workshop!&lt;/p
&gt;&lt;div class="figure"
&gt;&lt;img src="http://gyazo.com/e55747c4ae68d95ba9bc53ea7f606911.png"
   /&gt;&lt;p class="caption"
  &gt;&lt;/p
  &gt;&lt;/div
&gt;&lt;h2 id="misc"
&gt;Misc&lt;/h2
&gt;&lt;p
&gt;Before and after the workshop some of the attendees had lunch and dinner with good Vim conversation. The topics were a lot.. vimshell, CoffeeScript, Titanium, HootSuite, Twitter, Ruby core, the ultimate programming language Zimbu, PHP vs Vim script, Emacs lisp and etc...&lt;/p
&gt;&lt;h2 id="quotes"
&gt;Quotes&lt;/h2
&gt;&lt;ul
&gt;&lt;li
  &gt;&amp;quot;It's... it's not the Vim I knew...&amp;quot;&lt;/li
  &gt;&lt;li
  &gt;&amp;quot;I came to Japan from San Francisco only for attending at this workshop&amp;quot;&lt;/li
  &gt;&lt;li
  &gt;&amp;quot;Wow! HootSuite for iPad works amazingly!!!&amp;quot;&lt;/li
  &gt;&lt;/ul
&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-5965733088140670780?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/5965733088140670780/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2011/05/vim-workshop-in-tokyo-japan-in-may.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/5965733088140670780'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/5965733088140670780'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2011/05/vim-workshop-in-tokyo-japan-in-may.html' title='A Vim Workshop in Tokyo, Japan in May'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm6.static.flickr.com/5269/5760569281_3dd19652df_t.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-8072568876370076385</id><published>2011-05-09T23:16:00.001-07:00</published><updated>2011-05-09T23:18:43.459-07:00</updated><title type='text'>Workshops in Amagasaki, Japan by Me</title><content type='html'>&lt;p&gt;I organized the 7th Vim workshop and a CoffeeScript workshop in &lt;a href="http://ow.ly/4QUOy"&gt;Amagasaki, Japan&lt;/a&gt; on the last Saturday.&lt;/p&gt;
&lt;p&gt;About 20 to 30 people attended the workshops. Even though the room had an air conditioner, the room was so hot and humid like sauna by them (and their MacBooks.)&lt;/p&gt;
&lt;p&gt;I was supposed to make presentations with demonstrations, but unfortunately I forgot bringing my mini-DVI port for my initial version of MacBook Air. There were many MacBook Air attendees but nobody had the same version to me. I eventually gave up using my computer and just made presentation by friends' computers. Sorry for missing demonstrations.&lt;/p&gt;
&lt;h2 id="vim-workshop7"&gt;Vim Workshop#7&lt;/h2&gt;
&lt;p&gt;There were five talks&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Recommended Vim plugins (by me)&lt;/li&gt;
&lt;li&gt;The implementation of lingr.vim (by &lt;a href="http://twitter.com/tsukkee"&gt;tsukkee&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Bundle with Vundle (by &lt;a href="http://twitter.com/kozo2"&gt;kozo2&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Unite is useful, and rails.vim as well (by &lt;a href="http://twitter.com/Sixeight"&gt;Sixeight&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;All about vital.vim (by me)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I broadcasted them and recorded some of them (I just forgot recording the others.) &lt;a href="http://ustream.tv/channel/uji"&gt;&lt;code class="url"&gt;http://ustream.tv/channel/uji&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="coffeescript-workshop"&gt;CoffeeScript Workshop&lt;/h2&gt;
&lt;p&gt;There were five talks.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Introduction to CoffeeScript -- syntax and usage (by me)&lt;/li&gt;
&lt;li&gt;Node.js on Windows, and introduction to no.de (by &lt;a href="http://twitter.com/cuzic"&gt;cuzic&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;iPhone app development with CoffeeScript and Titanium (by &lt;a href="http://twitter.com/nektixe"&gt;deguchi&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;TDD with Jasmine and CoffeeScript (by &lt;a href="nanki"&gt;http://twitter.com/nanki&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Details of CoffeeScript syntax (by &lt;a href="http://twitter.com/yhara"&gt;yhara&lt;/a&gt; and me)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="figure"&gt;
&lt;img src="http://gyazo.com/3f9061a9f723da7ae2d5d6355082dd67.png" alt="by fukui" /&gt;&lt;p class="caption"&gt;by fukui&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="see-also"&gt;See also&lt;/h2&gt;
&lt;p&gt;Blog entries written by attendees. All of then are written in Japanese.&lt;/p&gt;
&lt;p&gt;Vim&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://d.hatena.ne.jp/heavenshell/20110507"&gt;&lt;code class="url"&gt;http://d.hatena.ne.jp/heavenshell/20110507&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://relaxedcolumn.blog8.fc2.com/blog-entry-168.html"&gt;&lt;code class="url"&gt;http://relaxedcolumn.blog8.fc2.com/blog-entry-168.html&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://future-nyanco.blogspot.com/2011/05/vim-7-8.html"&gt;&lt;code class="url"&gt;http://future-nyanco.blogspot.com/2011/05/vim-7-8.html&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://spring-aki.com/archives/2011/05/vim%E5%8B%89%E5%BC%B7%E4%BC%9A7.html"&gt;&lt;code class="url"&gt;http://spring-aki.com/archives/2011/05/vim%E5%8B%89%E5%BC%B7%E4%BC%9A7.html&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://mattn.kaoriya.net/software/vim/20110510003736.htm"&gt;&lt;code class="url"&gt;http://mattn.kaoriya.net/software/vim/20110510003736.htm&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CoffeeScript&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://teq.g.hatena.ne.jp/aereal/20110508/1304785373"&gt;&lt;code class="url"&gt;http://teq.g.hatena.ne.jp/aereal/20110508/1304785373&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://nov.tdiary.net/20110507.html#p01"&gt;&lt;code class="url"&gt;http://nov.tdiary.net/20110507.html#p01&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://picasaweb.google.com/ofukui/CoffeeScript"&gt;&lt;code class="url"&gt;https://picasaweb.google.com/ofukui/CoffeeScript&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-8072568876370076385?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/8072568876370076385/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2011/05/workshops-in-amagasaki-japan-by-me.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/8072568876370076385'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/8072568876370076385'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2011/05/workshops-in-amagasaki-japan-by-me.html' title='Workshops in Amagasaki, Japan by Me'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-2503214830535426770</id><published>2011-02-22T08:12:00.001-08:00</published><updated>2011-03-07T08:38:54.934-08:00</updated><title type='text'>Vim 7.3 Conceal Current Issue</title><content type='html'>&lt;p
&gt;Vim 7.3 new feature Conceal has an issue that when you change your colorscheme the current conceal information will be partly removed automatically.&lt;/p
&gt;&lt;p
&gt;I found this issue with the combination of Haskell-Conceal plugin and unite-colorscheme plugin which internally uses tabpagecolorscheme plugin. Every time I moved the tab, the concealed text highlighted wrongly. After a research I figured out that it was not by changing the tab but by changing colorscheme into the same colorscheme.&lt;/p
&gt;&lt;p
&gt;First of all, the idiom to define a concealed token in a syntax file is (1) to define a &lt;code
  &gt;syntax match {your favourite name here} &amp;quot;{regexp}&amp;quot; conceal cchar={the replacement}&lt;/code
  &gt; (2) and to link the color by &lt;code
  &gt;highlight! link Conceal {token name}&lt;/code
  &gt;. Note that normal highlights only needs to &lt;code
  &gt;hightlight&lt;/code
  &gt; without the bang.&lt;/p
&gt;&lt;p
&gt;The main part of the implementation of &lt;code
  &gt;colorscheme&lt;/code
  &gt; command is defined as below which is from src/syntax.c of vim repository.&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;6755 /*
6756  * Load color file &amp;quot;name&amp;quot;.
6757  * Return OK for success, FAIL for failure.
6758  */
6759     int
6760 load_colors(name)
6761     char_u *name;
6762 {
6763     char_u *buf;
6764     int        retval = FAIL;
6765     static int recursive = FALSE;
6766 
6767     /* When being called recursively, this is probably because setting
6768      * 'background' caused the highlighting to be reloaded.  This means it is
6769      * working, thus we should return OK. */
6770     if (recursive)
6771    return OK;
6772 
6773     recursive = TRUE;
6774     buf = alloc((unsigned)(STRLEN(name) + 12));
6775     if (buf != NULL)
6776     {
6777    sprintf((char *)buf, &amp;quot;colors/%s.vim&amp;quot;, name);
6778    retval = source_runtime(buf, FALSE);
6779    vim_free(buf);
6780 #ifdef FEAT_AUTOCMD
6781    apply_autocmds(EVENT_COLORSCHEME, NULL, NULL, FALSE, curbuf);
6782 #endif
6783     }
6784     recursive = FALSE;
6785 
6786     return retval;
6787 }
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;Basically this function runs &lt;code
  &gt;:source colors/{the colorscheme name}.vim&lt;/code
  &gt; and them runs autocmds already registers in Colorscheme event. This function itself looks good.&lt;/p
&gt;&lt;p
&gt;Every colorscheme files run &lt;code
  &gt;:highlight clear&lt;/code
  &gt; in the beginning of the files. This removes all highlights except for user-defined ones. Thus it preserves syntactic information of each syntax files, but breaks conceal information given by each syntax files, because it's not treated as user-defined one but as just extended built-in one.&lt;/p
&gt;&lt;h2 id="possible-solutions"
&gt;Possible solutions&lt;/h2
&gt;&lt;p
&gt;I propose the following solutions. Each of them are independent and exclusive.&lt;/p
&gt;&lt;ol style="list-style-type: decimal;"
&gt;&lt;li
  &gt;Remove the procedure of removing conceal information from &lt;code
    &gt;:highlight clear&lt;/code
    &gt; command&lt;/li
  &gt;&lt;li
  &gt;Fix colorscheme command to recover the conceal information after changing colorscheme&lt;/li
  &gt;&lt;li
  &gt;The behaviour is specification. Just add documentation in Vim core to persuade conceal users to add autocmd event to change conceal again after colorscheme changed.&lt;/li
  &gt;&lt;/ol
&gt;&lt;p
&gt;The below is the patch for the solution (a).&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;diff --git src/syntax.c src/syntax.c
index 369311f..90165cf 100644
--- src/syntax.c
+++ src/syntax.c
@@ -6572,10 +6572,6 @@ static char *(highlight_init_light[]) =
  CENT(&amp;quot;ColorColumn term=reverse ctermbg=LightRed&amp;quot;,
       &amp;quot;ColorColumn term=reverse ctermbg=LightRed guibg=LightRed&amp;quot;),
 #endif
-#ifdef FEAT_CONCEAL
-   CENT(&amp;quot;Conceal ctermbg=DarkGrey ctermfg=LightGrey&amp;quot;,
-        &amp;quot;Conceal ctermbg=DarkGrey ctermfg=LightGrey guibg=DarkGrey guifg=LightGrey&amp;quot;),
-#endif
 #ifdef FEAT_AUTOCMD
  CENT(&amp;quot;MatchParen term=reverse ctermbg=Cyan&amp;quot;,
       &amp;quot;MatchParen term=reverse ctermbg=Cyan guibg=Cyan&amp;quot;),
@@ -6662,10 +6658,6 @@ static char *(highlight_init_dark[]) =
  CENT(&amp;quot;MatchParen term=reverse ctermbg=DarkCyan&amp;quot;,
       &amp;quot;MatchParen term=reverse ctermbg=DarkCyan guibg=DarkCyan&amp;quot;),
 #endif
-#ifdef FEAT_CONCEAL
-   CENT(&amp;quot;Conceal ctermbg=DarkGrey ctermfg=LightGrey&amp;quot;,
-        &amp;quot;Conceal ctermbg=DarkGrey ctermfg=LightGrey guibg=DarkGrey guifg=LightGrey&amp;quot;),
-#endif
 #ifdef FEAT_GUI
  &amp;quot;Normal gui=NONE&amp;quot;,
 #endif
&lt;/code
  &gt;&lt;/pre
&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-2503214830535426770?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/2503214830535426770/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2011/02/vim-73-conceal-current-issue.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/2503214830535426770'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/2503214830535426770'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2011/02/vim-73-conceal-current-issue.html' title='Vim 7.3 Conceal Current Issue'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-6792438964992472859</id><published>2011-02-05T20:04:00.001-08:00</published><updated>2011-02-05T21:02:44.574-08:00</updated><title type='text'>Delegation in Vim script</title><content type='html'>&lt;p
&gt;In case when you define a function F1 which behaves same as a given function F2 in Vim script, you may just choose the following cases depending on the arguments of F2.&lt;/p
&gt;&lt;p
&gt;The solution is just to use &lt;code
  &gt;call()&lt;/code
  &gt;.&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;function! F1(...)
  return call('F2', a:000)
endfunction
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;But if you also want to preserve the definition of arguments? There are still solution of each cases.&lt;/p
&gt;&lt;p
&gt;Named arguments (or no arguments)&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;function! F1(x)
  return F2(a:x)
endfunction
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;Unnamed arguments&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;function! F1(...)
  return call('F2', a:000)
endfunction
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;Then you can make mixed version, using &lt;code
  &gt;call()&lt;/code
  &gt;.&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;function! F1(x, ...)
  return call('F2', insert(deepcopy(a:000), a:x))
endfunction
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;Basically this is &amp;quot;cons&amp;quot;ing a named variable into the top of the list.&lt;/p
&gt;&lt;h2 id="summary"
&gt;Summary&lt;/h2
&gt;&lt;p
&gt;&lt;code
  &gt;call()&lt;/code
  &gt; is so handy.&lt;/p
&gt;&lt;p
&gt;Shougo Matsu, the neocomplcache and unite author, suggested me to use &lt;code
  &gt;call()&lt;/code
  &gt; instead of the following &amp;quot;First version&amp;quot; of this blog post. That's absolutely better idea than I had. Thanks Shougo!&lt;/p
&gt;&lt;h2 id="first-version"
&gt;First version&lt;/h2
&gt;&lt;p
&gt;The following sentense was legacy. I leave them just for your additional information.&lt;/p
&gt;&lt;p
&gt;Named arguments (or no arguments)&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;function! F1(x)
  return F2(a:x)
endfunction
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;Unnamed arguments&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;function! F1(...)
  return eval('F2(' . join(map(range(1, a:0), '&amp;quot;a:&amp;quot; . v:val'), ', ') . ')')
endfunction
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;This looks more difficult than it should be. Let me explain it.&lt;/p
&gt;&lt;p
&gt;&lt;code
  &gt;a:0&lt;/code
  &gt; is the number of the arguments of the function. If you call &lt;code
  &gt;F1(x, y, z)&lt;/code
  &gt;, &lt;code
  &gt;a:0&lt;/code
  &gt; is 3. You can access each arguments as &lt;code
  &gt;a:1&lt;/code
  &gt;, &lt;code
  &gt;a:2&lt;/code
  &gt; and &lt;code
  &gt;a:3&lt;/code
  &gt;.&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;range(1, a:0)
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;This becomes a list [1, 2, 3] if the number of the arguments of F1 is 3.&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;map(range(1, a:0), '&amp;quot;a:&amp;quot; . v:val'), ', ')
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;This becomes 'a:1, a:2, a:3'. Then you can make a string &lt;code
  &gt;&amp;quot;F2(a:1, a:2, a:3)&amp;quot;&lt;/code
  &gt; dynamically, and call it by &lt;code
  &gt;eval&lt;/code
  &gt;.&lt;/p
&gt;&lt;p
&gt;Then you can make mixed version easily.&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;function! F1(x, ...)
  return eval('F2(a:x, ' . join(map(range(1, a:0), '&amp;quot;a:&amp;quot; . v:val'), ', ') . ')')
endfunction
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;The difference is only just &lt;code
  &gt;&amp;quot;F2(a:x, &amp;quot;&lt;/code
  &gt; which was originally &lt;code
  &gt;&amp;quot;F2(&amp;quot;&lt;/code
  &gt;.&lt;/p
&gt;&lt;a href="http://ujihisa.blogspot.com/2011/02/delegation-in-vim-script.html" title="Standards “Delegation in Vim script” by @ujm" class="_hs_socialshare"&gt;Share&lt;/a&gt;&lt;script&gt;
var _hs = {
    size: 1
};
(function() {
    var h = document.createElement('script'); h.type = 'text/javascript'; h.async = true;
    h.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + 'd2l6uygi1pgnys.cloudfront.net/hootlet.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(h, s);
})();
&lt;/script&gt;


&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-6792438964992472859?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/6792438964992472859/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2011/02/delegation-in-vim-script.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/6792438964992472859'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/6792438964992472859'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2011/02/delegation-in-vim-script.html' title='Delegation in Vim script'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-7684130788000358636</id><published>2011-01-27T20:19:00.001-08:00</published><updated>2011-01-27T20:20:19.896-08:00</updated><title type='text'>How To Build MRI n Times Faster</title><content type='html'>&lt;p
&gt;&lt;a href="http://en.wikipedia.org/wiki/Clang"
  &gt;Clang&lt;/a
  &gt;, a compiler front end which you can use instead of gcc, can build MRI: Matz Ruby Implementation, only if you succeeded in avoiding all pitfalls.&lt;/p
&gt;&lt;h2 id="build-the-latest-llvm-and-clang"
&gt;Build the latest LLVM and Clang&lt;/h2
&gt;&lt;p
&gt;Mac OS X Snow Leopard has builtin &lt;code
  &gt;clang&lt;/code
  &gt; command but it's too old to build ruby. First of all, get the latest clang and it's dependency, the latest LLVM.&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;$ svn checkout http://llvm.org/svn/llvm-project/llvm/trunk llvm &amp;amp;&amp;amp; cd llvm/tools &amp;amp;&amp;amp; svn checkout http://llvm.org/svn/llvm-project/cfe/trunk clang &amp;amp;&amp;amp; cd ..
$ ./configure &amp;amp;&amp;amp; time make
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;Note that it takes &lt;em
  &gt;really&lt;/em
  &gt; long time. I recommend you not to build before you go away from keyboard for a while but to build before you go to bed.&lt;/p
&gt;&lt;h2 id="a-simple-test"
&gt;A simple test&lt;/h2
&gt;&lt;p
&gt;hello.c&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;#include&amp;lt;stdio.h&amp;gt;
int main() {
  puts(&amp;quot;Hello, world!&amp;quot;);
  return 0;
}
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;building on gcc and clang&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;$ time gcc hello.c -o hello-gcc
!!!        0.34 real         0.01 user         0.03 sys!!!

[%] /private/tmp
$ time ~/src/llvm/Debug+Asserts/bin/clang hello.c -o hello-clang
!!!        0.11 real         0.06 user         0.02 sys!!!
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;clang is &lt;em
  &gt;3 times faster&lt;/em
  &gt; than gcc to build the hello world code. The executable files work samel.&lt;/p
&gt;&lt;h2 id="ruby"
&gt;Ruby&lt;/h2
&gt;&lt;p
&gt;On GCC&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;$ git clone https://github.com/ruby/ruby.git ruby193-gcc
$ cd ruby193-gcc
$ autoconf
$ ./configure --prefix=`pwd`/local --enable-pthread --disable-install-doc --with-out-ext=tk\* --program-suffix=193 --with-readline-dir=/usr/local --with-arch=x86_64
$ time make
...
!!!      214.93 real       191.58 user        23.57 sys!!!
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;On Clang&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;$ git clone https://github.com/ruby/ruby.git ruby193
$ cd ruby193
$ ./configure --prefix=`pwd`/local --enable-pthread --disable-install-doc --with-out-ext=tk\* --program-suffix=193 --with-readline-dir=/usr/local PATH=/Users/ujihisa/src/llvm/Debug+Asserts/bin/:$PATH CC=/Users/ujihisa/src/llvm/Debug+Asserts/bin/clang CFLAGS=-Qunused-arguments CPPFLAGS=-Qunused-arguments --with-arch=x86_64
$ time make
!!!      932.06 real       883.44 user        31.09 sys!!!
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;It took 3 min 34.93 sec by GCC while it took 15 min 32.06 sec by Clang. GCC is 4.34 times faster than Clang to build MRI.&lt;/p
&gt;&lt;h2 id="pitfalls"
&gt;Pitfalls&lt;/h2
&gt;&lt;p
&gt;If you use &lt;code
  &gt;clang&lt;/code
  &gt; command of Mac OS X Snow Leopard, even though you'll succeed in finishing &lt;code
  &gt;make&lt;/code
  &gt; ruby 1.9.3, but you cannot do anything by the Ruby.&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;$ ./local/bin/ruby -ve 1
ruby 1.9.3dev (2011-01-25 trunk 30651) [x86_64-darwin10.6.0]
!!!dyld: lazy symbol binding failed: Symbol not found: _rb_encdb_declare!!!
!!!  Referenced from: /Users/ujihisa/git/ruby193/local/lib/ruby/1.9.1/x86_64-darwin10.6.0/enc/encdb.bundle!!!
!!!  Expected in: flat namespace!!!

!!!dyld: Symbol not found: _rb_encdb_declare!!!
!!!  Referenced from: /Users/ujihisa/git/ruby193/local/lib/ruby/1.9.1/x86_64-darwin10.6.0/enc/encdb.bundle!!!
!!!  Expected in: flat namespace!!!

!!!/Users/ujihisa/git/ruby193/local/lib/ruby/1.9.1/x86_64-darwin10.6.0/enc/encdb.bundle: [BUG] Segmentation fault!!!
!!!ruby 1.9.3dev (2011-01-25 trunk 30651) [x86_64-darwin10.6.0]!!!

!!!-- Control frame information -----------------------------------------------!!!
!!!c:0002 p:-537663266 s:0004 b:0004 l:000003 d:000003 TOP   !!!
!!!c:0001 p:0000 s:0002 b:0002 l:001dd8 d:001dd8 TOP   !!!


!!!-- See Crash Report log file under ~/Library/Logs/CrashReporter or ---------!!!
!!!-- /Library/Logs/CrashReporter, for the more detail of ---------------------!!!
!!!-- C level backtrace information -------------------------------------------!!!

!!!-- Other runtime information -----------------------------------------------!!!

!!!* Loaded script: ./local/bin/ruby!!!

!!!* Loaded features:!!!

!!!    0 enumerator.so!!!

!!![NOTE]!!!
!!!You may have encountered a bug in the Ruby interpreter or extension libraries.!!!
!!!Bug reports are welcome.!!!
!!!For details: http://www.ruby-lang.org/bugreport.html!!!


!!!vimshell: signal 6(SIGABRT) &amp;quot;./local/bin/ruby -ve 1&amp;quot;!!!
&lt;/code
  &gt;&lt;/pre
&gt;&lt;h2 id="conclusion"
&gt;Conclusion&lt;/h2
&gt;&lt;p
&gt;You can build Ruby 1.9.3 by Clang. It's 0.23 times faster than building by GCC.&lt;/p
&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-7684130788000358636?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/7684130788000358636/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2011/01/how-to-build-mri-n-times-faster.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/7684130788000358636'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/7684130788000358636'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2011/01/how-to-build-mri-n-times-faster.html' title='How To Build MRI n Times Faster'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-6054369477620054571</id><published>2011-01-05T09:27:00.001-08:00</published><updated>2011-01-05T09:28:14.977-08:00</updated><title type='text'>A Contributed Article to Kernel/VM Advent Calendar: VIM=VM</title><content type='html'>&lt;p
&gt;There are two kinds of programmers; one uses Vim and the other uses Emacs. I don't think there are positive counter opinions about that Emacs is not an editor but an environment. On the other hand, there are some opinions that Vim is an editor or not, even though everyone agrees with the fact that vi is an editor. Some people, including the author of this article, claim that Vim is a virtual machine. Here I give you instructions of a Vim plugin shadow.vim instead of explaining why Vim is VM directly.&lt;/p
&gt;&lt;div class="figure"
&gt;&lt;img src="http://gyazo.com/54801cc951f4dd0173f7c722c8857950.png"
   /&gt;&lt;p class="caption"
  &gt;&lt;/p
  &gt;&lt;/div
&gt;&lt;h2 id="shadow.vim"
&gt;shadow.vim&lt;/h2
&gt;&lt;p
&gt;The Vim plugin shadow.vim supports wrapping a virtual file with a program automatically with thin configuration.&lt;/p
&gt;&lt;p
&gt;Here it's a quote from a programmer:&lt;/p
&gt;&lt;blockquote
&gt;&lt;p
  &gt;&amp;quot;Nobody knows the Java code you committed is originally written in Scheme.&amp;quot;&lt;/p
  &gt;&lt;/blockquote
&gt;&lt;h2 id="usage"
&gt;Usage&lt;/h2
&gt;&lt;p
&gt;Assuming the product is &lt;code
  &gt;a.pl&lt;/code
  &gt;, create &lt;code
  &gt;a.pl.shd&lt;/code
  &gt; first.&lt;/p
&gt;&lt;p
&gt;a.pl (in Vim):&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;## ruby -e 'puts $&amp;lt;.read.gsub(/$/, &amp;quot;;&amp;quot;)'
$a = 1
print($a)
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;Open &lt;code
  &gt;a.pl&lt;/code
  &gt; in Vim. The Vim actually shows the contents of &lt;code
  &gt;a.pl.shd&lt;/code
  &gt;. When you save the file, the command in the first line without &lt;code
  &gt;##&lt;/code
  &gt; runs, then the actual &lt;code
  &gt;a.pl&lt;/code
  &gt; will be the result.&lt;/p
&gt;&lt;p
&gt;a.pl (actually):&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;$a = 1;
print($a);
&lt;/code
  &gt;&lt;/pre
&gt;&lt;h2 id="install"
&gt;Install&lt;/h2
&gt;&lt;p
&gt;Unarchive the zip file into a directory that is under &lt;code
  &gt;&amp;amp;rtp&lt;/code
  &gt; of your Vim, which stands for run time path, including &lt;code
  &gt;~/.vim&lt;/code
  &gt; dir.&lt;/p
&gt;&lt;h2 id="use-case"
&gt;Use Case&lt;/h2
&gt;&lt;p
&gt;Here there are three examples, but you can use more general purposes.&lt;/p
&gt;&lt;ul
&gt;&lt;li
  &gt;&lt;p
    &gt;Commit JavaScript files which was written in CoffeeScript&lt;/p
    &gt;&lt;ul
    &gt;&lt;li
      &gt;&lt;p
	&gt;before&lt;/p
	&gt;&lt;pre
	&gt;&lt;code
	  &gt;    ## coffee -csb
    f = (x) -&amp;gt; x + 1
    print f 10

    # vim: set ft=coffee :
&lt;/code
	  &gt;&lt;/pre
	&gt;&lt;/li
      &gt;&lt;li
      &gt;&lt;p
	&gt;after&lt;/p
	&gt;&lt;pre
	&gt;&lt;code
	  &gt;    var f;
    f = function(x) {
      return x + 1;
    };
    print(f(10));
&lt;/code
	  &gt;&lt;/pre
	&gt;&lt;/li
      &gt;&lt;/ul
    &gt;&lt;/li
  &gt;&lt;li
  &gt;Use &lt;code
    &gt;cpp&lt;/code
    &gt; command before committing Java files.&lt;/li
  &gt;&lt;li
  &gt;&lt;p
    &gt;Markdown, Haml or something else to HTML&lt;/p
    &gt;&lt;/li
  &gt;&lt;/ul
&gt;&lt;h2 id="more-examples"
&gt;More examples&lt;/h2
&gt;&lt;p
&gt;You can write code in C and save the file as GNU Assembly Language on your Linux automatically, so you can avoid portability.&lt;/p
&gt;&lt;h2 id="references"
&gt;References&lt;/h2
&gt;&lt;ul
&gt;&lt;li
  &gt;VIM=VM &lt;a href="http://www.slideshare.net/Shougo/vim-presentation-5330807"
    &gt;&lt;code
      &gt;http://www.slideshare.net/Shougo/vim-presentation-5330807&lt;/code
      &gt;&lt;/a
    &gt; by Shougo&lt;/li
  &gt;&lt;li
  &gt;&lt;a href="http://atnd.org/events/10701"
    &gt;&lt;code
      &gt;http://atnd.org/events/10701&lt;/code
      &gt;&lt;/a
    &gt;&lt;/li
  &gt;&lt;/ul
&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-6054369477620054571?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/6054369477620054571/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2011/01/contributed-article-to-kernelvm-advent.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/6054369477620054571'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/6054369477620054571'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2011/01/contributed-article-to-kernelvm-advent.html' title='A Contributed Article to Kernel/VM Advent Calendar: VIM=VM'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-6751968817671117484</id><published>2010-12-13T17:49:00.001-08:00</published><updated>2010-12-13T17:49:32.295-08:00</updated><title type='text'>Búsqueda/Instalación Librerías RubyGems Fácilmente</title><content type='html'>&lt;p
&gt;¿Cómo se puede explorar y tratar de librerías RubyGems? Hay una gran cantidad de joyas como las estrellas en el cielo. Si lo desea, estar de pie sobre los hombros de gigantes.&lt;/p
&gt;&lt;p
&gt;Una escena típica de cuando usted está buscando una librería que cumple su trabajo sería como el siguiente, por ejemplo, que busca una librería que está relacionado con DataMapper.&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;$ gem search dm
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;No consigues nada porque se le olvidó especificar &lt;code
  &gt;-r&lt;/code
  &gt; opción.&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;$ gem search dm -r
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;Usted obtiene demasiados resultados, porque hay demasiadas joyas que incluyen &amp;quot;dm&amp;quot; en el nombre, por ejemplo &amp;quot;admin&amp;quot; algo.&lt;/p
&gt;&lt;p
&gt;De todos modos, que finalmente encontró una buena librería cuyo nombre es &amp;quot;dm-is-persistent_state_machine&amp;quot;.&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt; $ gem install dm-is-persistent_states_machine
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;Este failes porque el nombre de la librería correcta es &amp;quot;dm-is-persistent_state_machine&amp;quot;, mientras que ha escrito &amp;quot;dm-is-persistent_states_machine&amp;quot;. Sí, eso es muy difícil de escribir correctamente cuando el nombre de la librería es muy larga. Puede ser difícil si el nombre no está en su lengua materna. (&lt;code
  &gt;*1&lt;/code
  &gt;)&lt;/p
&gt;&lt;h2 id="unite-gem"
&gt;unite-gem&lt;/h2
&gt;&lt;p
&gt;Una solución es usar un plugin Unite &lt;a href="http://www.vim.org/scripts/script.php?script_id=3348"
  &gt;unite-gem&lt;/a
  &gt;. Después de instalar este plugin, basta con ejecutar&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt; :Unite gem
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;y el tipo nada. Verá los siguientes resultados.&lt;/p
&gt;&lt;div class="figure"
&gt;&lt;img src="http://gyazo.com/8b86175cf6833ffe55931a7b55fdd978.png"
   /&gt;&lt;p class="caption"
  &gt;&lt;/p
  &gt;&lt;/div
&gt;&lt;p
&gt;y se puede reducir el número de candidatos.&lt;/p
&gt;&lt;div class="figure"
&gt;&lt;img src="http://gyazo.com/1cea7eb58c98adb8216a7432c772cce9.png"
   /&gt;&lt;p class="caption"
  &gt;&lt;/p
  &gt;&lt;/div
&gt;&lt;p
&gt;a continuación, simplemente pulse &lt;code
  &gt;&amp;lt;Cr&amp;gt;&lt;/code
  &gt;... el proceso de instalación se produjo. Usted no tiene que introducir el nombre completo de la librería.&lt;/p
&gt;&lt;h2 id="nota"
&gt;Nota&lt;/h2
&gt;&lt;ul
&gt;&lt;li
  &gt;(&lt;code
    &gt;*1&lt;/code
    &gt;): por ejemplo, muchas personas trataron de tipo &amp;quot;nokogiri&amp;quot;, pero mal escrita como &amp;quot;nokogirl&amp;quot;. Por último los autores Nokogiri realizó una joya alias &amp;quot;nokogirl&amp;quot; y todo el mundo se puso feliz. Este blog es sólo givin una versión más general de la solución.&lt;/li
  &gt;&lt;/ul
&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-6751968817671117484?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/6751968817671117484/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/12/busquedainstalacion-librerias-rubygems.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/6751968817671117484'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/6751968817671117484'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/12/busquedainstalacion-librerias-rubygems.html' title='Búsqueda/Instalación Librerías RubyGems Fácilmente'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-8230812807604837852</id><published>2010-12-13T09:10:00.001-08:00</published><updated>2010-12-13T21:17:04.239-08:00</updated><title type='text'>How To Write And Show Multibyte Characters With Snap Framework</title><content type='html'>&lt;p
&gt;I'm playing with Snap these days. Snap is a web framework for Haskell.&lt;/p
&gt;&lt;p
&gt;The default template of application code will be like below&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;{-# LANGUAGE OverloadedStrings #-}
module Main where

import           Control.Applicative
import           Snap.Types
import           Snap.Util.FileServe
import           Text.Templating.Heist
import           Text.Templating.Heist.TemplateDirectory

import           Glue
import           Server


main :: IO ()
main = do
    td &amp;lt;- newTemplateDirectory' &amp;quot;templates&amp;quot; emptyTemplateState
    quickServer $ templateHandler td defaultReloadHandler $ \ts -&amp;gt;
        ifTop (writeBS &amp;quot;hello&amp;quot;) &amp;lt;|&amp;gt;
        route [ (&amp;quot;foo&amp;quot;, writeBS &amp;quot;bar&amp;quot;)
              , (&amp;quot;echo/:echoparam&amp;quot;, echoHandler)
              ] &amp;lt;|&amp;gt;
        templateServe ts &amp;lt;|&amp;gt;
        dir &amp;quot;static&amp;quot; (fileServe &amp;quot;.&amp;quot;)


echoHandler :: Snap ()
echoHandler = do
    param &amp;lt;- getParam &amp;quot;echoparam&amp;quot;
    maybe (writeBS &amp;quot;must specify echo/param in URL&amp;quot;)
          writeBS param
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;See the following line in main function:&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;        ifTop (writeBS &amp;quot;hello&amp;quot;) &amp;lt;|&amp;gt;
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;This just shows a text written in &lt;code
  &gt;ByteString&lt;/code
  &gt; &amp;quot;hello&amp;quot; to browser.&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;$ cabal install
$ {your application name} 3000
$ curl http://localhost:3000
hello
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;You can change the message &amp;quot;hello&amp;quot; to something and show the message on browser, but if the text is non-ascii like utf-8, you have to change other places as well. See the following patch:&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;diff --git snapfib.cabal snapfib.cabal
index d7a98fe..35b5c92 100644
--- snapfib.cabal
+++ snapfib.cabal
@@ -28,7 +28,8 @@ Executable snapfib
     text,
     containers,
     MonadCatchIO-transformers,
-    filepath &amp;gt;= 1.1 &amp;amp;&amp;amp; &amp;lt;1.2
+    filepath &amp;gt;= 1.1 &amp;amp;&amp;amp; &amp;lt;1.2,
+    utf8-string

   if impl(ghc &amp;gt;= 6.12.0)
     ghc-options: -threaded -Wall -fwarn-tabs -funbox-strict-fields -O2
diff --git src/Main.hs src/Main.hs
index d5b24c4..036b2db 100644
--- src/Main.hs
+++ src/Main.hs
@@ -9,13 +9,14 @@ import           Text.Templating.Heist.TemplateDirectory

 import           Glue
 import           Server
+import           Data.Text


 main :: IO ()
 main = do
     td &amp;lt;- newTemplateDirectory' &amp;quot;templates&amp;quot; emptyTemplateState
     quickServer $ templateHandler td defaultReloadHandler $ \ts -&amp;gt;
-        ifTop (writeBS &amp;quot;hello&amp;quot;) &amp;lt;|&amp;gt;
+        ifTop (writeText $ pack &amp;quot;こんにちはこんにちは!&amp;quot;) &amp;lt;|&amp;gt;
         route [ (&amp;quot;foo&amp;quot;, writeBS &amp;quot;bar&amp;quot;)
               , (&amp;quot;echo/:echoparam&amp;quot;, echoHandler)
               ] &amp;lt;|&amp;gt;
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;The function &lt;code
  &gt;writeBS&lt;/code
  &gt; in Snap receives &lt;code
  &gt;ByteString&lt;/code
  &gt; and shows the message to browser as a response. This cannot handle UTF-8 strings for some reason, so instead of using &lt;code
  &gt;writeBS&lt;/code
  &gt; with &lt;code
  &gt;ByteString&lt;/code
  &gt; you have to use &lt;code
  &gt;writeText&lt;/code
  &gt; with &lt;code
  &gt;Text&lt;/code
  &gt; represented message. You can convert into &lt;code
  &gt;Text&lt;/code
  &gt; with &lt;code
  &gt;Data.Text.pack&lt;/code
  &gt; function.&lt;/p
&gt;&lt;h2 id="see-also"
&gt;See also:&lt;/h2
&gt;&lt;ul
&gt;&lt;li
  &gt;&lt;a href="http://ujihisa.blogspot.com/2010/12/writing-fibonacci-web-server-in-haskell.html"
    &gt;&lt;code
      &gt;http://ujihisa.blogspot.com/2010/12/writing-fibonacci-web-server-in-haskell.html&lt;/code
      &gt;&lt;/a
    &gt;&lt;/li
  &gt;&lt;/ul
&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-8230812807604837852?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/8230812807604837852/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/12/how-to-write-and-show-multibyte.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/8230812807604837852'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/8230812807604837852'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/12/how-to-write-and-show-multibyte.html' title='How To Write And Show Multibyte Characters With Snap Framework'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-1473346172962459184</id><published>2010-12-08T01:19:00.001-08:00</published><updated>2010-12-08T01:19:25.188-08:00</updated><title type='text'>Ruby-like Object-oriented Notation in Haskell</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;This article doesn't discuss about something practical but about something experimental.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import Prelude hiding ((.))

send :: Object -&amp;amp;gt; Method -&amp;amp;gt; Object
send (Fixnum value) (Method "to_s") = Str $ show value
send _ _ = undefined

(.) = send

data Object = Fixnum Int | Str String deriving Show
data Method = Method String deriving Show

main = print $ x.to_s
  where
    x = Fixnum 10
    to_s = Method "to_s"
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;See the line in main function definition: &lt;code&gt;print $ x.to_s&lt;/code&gt;. This looks like Ruby.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;You can hide the definition of Haskell Prelude "." and can define your own function which name is "."; here I defined &lt;code&gt;send&lt;/code&gt; first then made an alias of it.&lt;/li&gt;&lt;li&gt;Object and sending method into an object are like just a data and a function which receives an argument of a specific type unless you think about class or prototype; or just, say, "performance."&lt;/li&gt;&lt;/ul&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-1473346172962459184?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/1473346172962459184/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/12/ruby-like-object-oriented-notation-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/1473346172962459184'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/1473346172962459184'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/12/ruby-like-object-oriented-notation-in.html' title='Ruby-like Object-oriented Notation in Haskell'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-6383640695433827804</id><published>2010-12-06T19:02:00.001-08:00</published><updated>2010-12-06T19:04:12.085-08:00</updated><title type='text'>Writing Fibonacci Web Server in Haskell</title><content type='html'>&lt;p
&gt;A practice: implementing a web service which receives a number by URL parameter and returns the corresponding Fibonacci sequence number.&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;GET
http://localhost:8000/fib/10
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;returns&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;fib(10) = 55
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;I used &lt;a href="http://snapframework.com/"
  &gt;Snap Framework&lt;/a
  &gt;.&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;$ mkdir snapfib
$ cd snapfib
$ snap init
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;This generates &lt;a href="https://github.com/ujihisa/snapfib/commit/3037ba6de8ec7bfb15f76912019c74c35a1a6b75"
  &gt;an empty snap project files&lt;/a
  &gt;. then&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;$ cabal install
$ snapfib
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;builds the codes and installs a command &lt;code
  &gt;snapfib&lt;/code
  &gt; in your &lt;code
  &gt;~/.cabal/bin/snapfib&lt;/code
  &gt;. You may run the app locally with the default port 8000; you may open the default page, hello world, on your browser.&lt;/p
&gt;&lt;p
&gt;Then &lt;a href="https://github.com/ujihisa/snapfib/commit/13771bce4cf575e27c89cc3b3c548eb393836194"
  &gt;implement fib sequence, a utility function, and the controller/view&lt;/a
  &gt;. This allows you to get the Fibonacci sequence number just by URL parameter.&lt;/p
&gt;&lt;p
&gt;Below is the main routine code from the repository.&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;{-# LANGUAGE OverloadedStrings #-}
module Main where

import           Control.Applicative
import           Snap.Types
import           Snap.Util.FileServe
import           Text.Templating.Heist
import           Text.Templating.Heist.TemplateDirectory

import           Glue
import           Server
import           Data.ByteString.Char8 (pack, unpack)

fibs :: [Integer]
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)

fibInString :: Int -&amp;gt; String
fibInString n = &amp;quot;fib(&amp;quot; ++ show n ++ &amp;quot;) = &amp;quot; ++ show (fibs !! n)

main :: IO ()
main = do
    td &amp;lt;- newTemplateDirectory' &amp;quot;templates&amp;quot; emptyTemplateState
    quickServer $ templateHandler td defaultReloadHandler $ \ts -&amp;gt;
        ifTop (writeBS &amp;quot;hello world&amp;quot;) &amp;lt;|&amp;gt;
        route [ (&amp;quot;foo&amp;quot;, writeBS &amp;quot;bar&amp;quot;)
              , (&amp;quot;fib/:n&amp;quot;, fibHandler)
              ] &amp;lt;|&amp;gt;
        templateServe ts &amp;lt;|&amp;gt;
        dir &amp;quot;static&amp;quot; (fileServe &amp;quot;.&amp;quot;)


fibHandler :: Snap ()
fibHandler = do
    param &amp;lt;- getParam &amp;quot;n&amp;quot;
    maybe (writeBS &amp;quot;must specify fib/n in URL&amp;quot;)
          (writeBS . pack . fibInString . read . unpack) param
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;&lt;code
  &gt;(writeBS . pack . fibInString . read . unpack) param&lt;/code
  &gt; is converting &lt;code
  &gt;param :: Maybe ByteString&lt;/code
  &gt; into &lt;code
  &gt;Int&lt;/code
  &gt;, getting a Fibonacci sequence number in String, converting into ByteString again, and passing it to &lt;code
  &gt;writeBS&lt;/code
  &gt; function which is defined in Snap Framework.&lt;/p
&gt;&lt;p
&gt;It was not difficult or complicated to implement such a simple web service in Haskell as long as you have basic Haskell knowledges like Maybe Monad or String manipulations. The problem was, in my opinion, it took long time to build the web app. Every time you fix your code, you have to wait for the compilation before you access your web service.&lt;/p
&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-6383640695433827804?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/6383640695433827804/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/12/writing-fibonacci-web-server-in-haskell.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/6383640695433827804'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/6383640695433827804'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/12/writing-fibonacci-web-server-in-haskell.html' title='Writing Fibonacci Web Server in Haskell'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-4040083755401557380</id><published>2010-12-02T17:23:00.001-08:00</published><updated>2010-12-02T17:23:08.986-08:00</updated><title type='text'>Investing The Methods Of An Object On Unite</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;How often do you use &lt;code&gt;Object#methods&lt;/code&gt;? That's convenient particularly on IRB.&lt;/p&gt;&lt;div class='figure'&gt;&lt;img alt='methods on irb' src='http://gyazo.com/e7c5a7ed7d7fa24bc01628f3f8a4469d.png'/&gt;&lt;p class='caption'&gt;methods on irb&lt;/p&gt;&lt;/div&gt;&lt;p&gt;This is also available on &lt;a href='https://github.com/Shougo/unite.vim'&gt;Unite.vim&lt;/a&gt;. Write the following code on your &lt;code&gt;~/.vimrc&lt;/code&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;let s:unite_source = {
      \ 'name': 'evalruby',
      \ 'is_volatile': 1,
      \ 'required_pattern_length': 1,
      \ 'max_candidates': 30,
      \ }

function! s:unite_source.gather_candidates(args, context)
  if a:context.input[-1:] == '.'
    let methods = split(
          \ unite#util#system(printf('ruby -e "puts %s.methods"', a:context.input[:-2])),
          \ "\n")
    call map(methods, printf("'%s' . v:val", a:context.input))
  else
    let methods = [a:context.input]
  endif
  return map(methods, '{
        \ "word": v:val,
        \ "source": "evalruby",
        \ "kind": "command",
        \ "action__command": printf("!ruby -e \"p %s\"", v:val),
        \ }')
endfunction

call unite#define_source(s:unite_source)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Execute &lt;code&gt;:Unite evalruby&lt;/code&gt; on your Vim, and write an expression.&lt;/p&gt;&lt;div class='figure'&gt;&lt;img alt='unite' src='http://gyazo.com/7abfd2124e5af4b8c4a3b910de2d9e0b.png'/&gt;&lt;p class='caption'&gt;unite&lt;/p&gt;&lt;/div&gt;&lt;h2 id='ruby-advent-calendar-jp-en-2010'&gt;Ruby Advent Calendar jp-en: 2010&lt;/h2&gt;&lt;p&gt;This entry is for the event &lt;a href='http://atnd.org/events/10439'&gt;Ruby Advent Calendar jp-en: 2010&lt;/a&gt;. The previous post was from &lt;a href='http://route477.net/e/?date=20101201#p01'&gt;yhara&lt;/a&gt; and the next post will be from &lt;a href='http://twitter.com/nari_en'&gt;authorNari&lt;/a&gt;. I'm sure he will write an entry about GC.&lt;/p&gt;&lt;p&gt;I also had written an entry of the event last year &lt;a href='http://ujihisa.blogspot.com/2009/11/write-implementation-and-spec-on-same.html'&gt;&lt;code&gt;http://ujihisa.blogspot.com/2009/11/write-implementation-and-spec-on-same.html&lt;/code&gt;&lt;/a&gt;. Time flees away without delay.&lt;/p&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-4040083755401557380?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/4040083755401557380/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/12/investing-methods-of-object-on-unite.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/4040083755401557380'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/4040083755401557380'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/12/investing-methods-of-object-on-unite.html' title='Investing The Methods Of An Object On Unite'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-3440809661730784726</id><published>2010-11-23T20:14:00.001-08:00</published><updated>2010-11-23T23:19:55.606-08:00</updated><title type='text'>Ruby 1.9.2 in Production with Tatsuhiro Ujihisa</title><content type='html'>&lt;p
&gt;(This is the presentation slides set for vancouver ruby meetup)&lt;/p
&gt;&lt;h2 id="before-the-talk..."
&gt;Before the talk...&lt;/h2
&gt;&lt;ul
&gt;&lt;li
  &gt;two questions&lt;/li
  &gt;&lt;li
  &gt;easy one and normal one&lt;/li
  &gt;&lt;/ul
&gt;&lt;h2 id="question-1"
&gt;Question 1&lt;/h2
&gt;&lt;p
&gt;An easy Ruby quiz: How to define a method without using &amp;quot;def&amp;quot; keyword? (only with pure Ruby)&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;def a
  :something
end
p a #=&amp;gt; :something
&lt;/code
  &gt;&lt;/pre
&gt;&lt;h2 id="sample-answer"
&gt;Sample answer&lt;/h2
&gt;&lt;pre
&gt;&lt;code
  &gt;self.class.module_eval do
  define_method(:a) do
    :something
  end
end
p a
&lt;/code
  &gt;&lt;/pre
&gt;&lt;h2 id="or"
&gt;Or&lt;/h2
&gt;&lt;pre
&gt;&lt;code
  &gt;eval 'def a; :something; end'
p a
&lt;/code
  &gt;&lt;/pre
&gt;&lt;ul
&gt;&lt;li
  &gt;There's no keyword def but string containing 'def'&lt;/li
  &gt;&lt;/ul
&gt;&lt;p
&gt;I think there are a lot more answers&lt;/p
&gt;&lt;h2 id="question-2"
&gt;Question 2&lt;/h2
&gt;&lt;p
&gt;A normal Ruby quiz: How to assign a value to a local variable without using assignment operator &amp;quot;=&amp;quot;? (only with pure Ruby)&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;a = :something
p a #=&amp;gt; :something
&lt;/code
  &gt;&lt;/pre
&gt;&lt;h2 id="sample-answer-1"
&gt;Sample answer 1&lt;/h2
&gt;&lt;pre
&gt;&lt;code
  &gt;for a in [:something]; end

p a
&lt;/code
  &gt;&lt;/pre
&gt;&lt;ul
&gt;&lt;li
  &gt;&amp;quot;Local variable&amp;quot; is very special in Ruby&lt;/li
  &gt;&lt;li
  &gt;Declaring a new local variable is completely static&lt;/li
  &gt;&lt;/ul
&gt;&lt;p
&gt;One more answer which is only on 1.9&lt;/p
&gt;&lt;h2 id="sample-answer-2"
&gt;Sample answer 2&lt;/h2
&gt;&lt;pre
&gt;&lt;code
  &gt;/(?&amp;lt;a&amp;gt;).*/ =~ ''
eval 'a=:something'

p a
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;There are a match operator &lt;code
  &gt;=~&lt;/code
  &gt; and a string which contains &lt;code
  &gt;=&lt;/code
  &gt;, but no assignment operator &lt;code
  &gt;=&lt;/code
  &gt;.&lt;/p
&gt;&lt;h2 id="ruby-1.9.2-in-production-with-tatsuhiro-ujihisa"
&gt;Ruby 1.9.2 in Production with Tatsuhiro Ujihisa&lt;/h2
&gt;&lt;div class="figure"
&gt;&lt;img src="http://www.h-online.com/imgs/43/5/5/8/3/2/8/ruby-logo-200-055ec6d14ab80eb7.png" alt="image"
   /&gt;&lt;p class="caption"
  &gt;image&lt;/p
  &gt;&lt;/div
&gt;&lt;h2 id="this-talk-contains"
&gt;This talk contains&lt;/h2
&gt;&lt;ol style="list-style-type: decimal;"
&gt;&lt;li
  &gt;What is Ruby 1.9.2?&lt;/li
  &gt;&lt;li
  &gt;Differences between 1.8..1.9&lt;/li
  &gt;&lt;li
  &gt;Differences between 1.9.1..1.9.2&lt;/li
  &gt;&lt;li
  &gt;Differences between 1.9.2..1.9.3&lt;/li
  &gt;&lt;/ol
&gt;&lt;h2 id="the-summary-of-this-talk"
&gt;The summary of this talk&lt;/h2
&gt;&lt;p
&gt;&amp;quot;Ruby 1.9.2 makes your code cleaner and easier to maintain.&amp;quot;&lt;/p
&gt;&lt;h2 id="ruby-versions"
&gt;Ruby versions&lt;/h2
&gt;&lt;ul
&gt;&lt;li
  &gt;Ruby 1.8.6&lt;ul
    &gt;&lt;li
      &gt;Mar 2007&lt;/li
      &gt;&lt;/ul
    &gt;&lt;/li
  &gt;&lt;li
  &gt;Ruby 1.8.7&lt;ul
    &gt;&lt;li
      &gt;May 2008&lt;/li
      &gt;&lt;/ul
    &gt;&lt;/li
  &gt;&lt;li
  &gt;Ruby 1.9.0&lt;ul
    &gt;&lt;li
      &gt;Dec 2007&lt;/li
      &gt;&lt;/ul
    &gt;&lt;/li
  &gt;&lt;li
  &gt;Ruby 1.9.1&lt;ul
    &gt;&lt;li
      &gt;Jan 2009&lt;/li
      &gt;&lt;/ul
    &gt;&lt;/li
  &gt;&lt;li
  &gt;Ruby 1.9.2&lt;ul
    &gt;&lt;li
      &gt;Aug 2010&lt;/li
      &gt;&lt;/ul
    &gt;&lt;/li
  &gt;&lt;/ul
&gt;&lt;h2 id="ruby-versions-1"
&gt;Ruby versions&lt;/h2
&gt;&lt;ul
&gt;&lt;li
  &gt;Ruby 1.8.6&lt;ul
    &gt;&lt;li
      &gt;Mar 2007&lt;/li
      &gt;&lt;/ul
    &gt;&lt;/li
  &gt;&lt;li
  &gt;Ruby 1.9.0&lt;ul
    &gt;&lt;li
      &gt;Dec 2007&lt;/li
      &gt;&lt;li
      &gt;&lt;em
	&gt;Rails 2.0&lt;/em
	&gt;&lt;/li
      &gt;&lt;/ul
    &gt;&lt;/li
  &gt;&lt;li
  &gt;Ruby 1.8.7&lt;ul
    &gt;&lt;li
      &gt;May 2008&lt;/li
      &gt;&lt;/ul
    &gt;&lt;/li
  &gt;&lt;li
  &gt;Ruby 1.9.1&lt;ul
    &gt;&lt;li
      &gt;Jan 2009&lt;/li
      &gt;&lt;/ul
    &gt;&lt;/li
  &gt;&lt;li
  &gt;Ruby 1.9.2&lt;ul
    &gt;&lt;li
      &gt;Aug 2010&lt;/li
      &gt;&lt;li
      &gt;&lt;em
	&gt;Rails 3.0&lt;/em
	&gt;&lt;/li
      &gt;&lt;/ul
    &gt;&lt;/li
  &gt;&lt;/ul
&gt;&lt;h2 id="background-ruby-versions"
&gt;Background: Ruby versions&lt;/h2
&gt;&lt;ul
&gt;&lt;li
  &gt;All of them are officialy stable version&lt;/li
  &gt;&lt;li
  &gt;But Ruby 1.9 series didn't look like stable&lt;/li
  &gt;&lt;/ul
&gt;&lt;h2 id="whats-new"
&gt;What's new?&lt;/h2
&gt;&lt;ul
&gt;&lt;li
  &gt;Which problems did 1.9 solved?&lt;/li
  &gt;&lt;li
  &gt;How can you write code easily?&lt;/li
  &gt;&lt;li
  &gt;-&amp;gt; Examples&lt;/li
  &gt;&lt;/ul
&gt;&lt;h2 id="problems-and-solutions"
&gt;Problems and solutions&lt;/h2
&gt;&lt;ul
&gt;&lt;li
  &gt;Verbose hash notation&lt;/li
  &gt;&lt;li
  &gt;Difficulty in process handling&lt;/li
  &gt;&lt;li
  &gt;etc..&lt;/li
  &gt;&lt;/ul
&gt;&lt;h2 id="problem-1"
&gt;Problem 1&lt;/h2
&gt;&lt;p
&gt;About syntax&lt;/p
&gt;&lt;h2 id="problem-1-1"
&gt;Problem 1&lt;/h2
&gt;&lt;p
&gt;JSON is cool. Dictionary in Erlang is cool. Hash in Ruby is...?&lt;/p
&gt;&lt;p
&gt;JavaScript or Erlang:&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;{a: 1, b: 2, c: 3}
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;Ruby:&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;{:a =&amp;gt; 1, :b =&amp;gt; 2, :c =&amp;gt; 3}
&lt;/code
  &gt;&lt;/pre
&gt;&lt;h2 id="new-hash-syntax"
&gt;1.9.2 new Hash syntax&lt;/h2
&gt;&lt;p
&gt;This solved the problem&lt;/p
&gt;&lt;p
&gt;Ruby:&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;{a: 1, b: 2, c: 3}
&lt;/code
  &gt;&lt;/pre
&gt;&lt;h2 id="this-issue-mattered-particularly-in.."
&gt;This issue mattered particularly in..&lt;/h2
&gt;&lt;p
&gt;Haml, the tool everyone is using, needs a lot of hash.&lt;/p
&gt;&lt;p
&gt;HTML:&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;&amp;lt;img src=&amp;quot;a.jpg&amp;quot; width=&amp;quot;64&amp;quot; height=&amp;quot;128&amp;quot;&amp;gt;&amp;lt;/img&amp;gt;
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;Haml with ruby variables:&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;%img{:src =&amp;gt; icon_path, :width =&amp;gt; icon[:width], :height =&amp;gt; icon[:height]}
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;(the below doesn't work)&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;%img(src=icon_path width=icon[:width] height=icon[:height])
&lt;/code
  &gt;&lt;/pre
&gt;&lt;h2 id="this-issue-mattered-particularly-in..-1"
&gt;This issue mattered particularly in..&lt;/h2
&gt;&lt;p
&gt;Using 1.9.2 new hash syntax&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;%img{src: icon_path, width: icon[:width], height: icon[:height]}
&lt;/code
  &gt;&lt;/pre
&gt;&lt;h2 id="problem-2"
&gt;Problem 2&lt;/h2
&gt;&lt;ul
&gt;&lt;li
  &gt;About builtin methods&lt;/li
  &gt;&lt;/ul
&gt;&lt;h2 id="problem-2-1"
&gt;Problem 2&lt;/h2
&gt;&lt;p
&gt;&lt;code
  &gt;system&lt;/code
  &gt; or `` operator lacked some important functionalities.&lt;/p
&gt;&lt;ul
&gt;&lt;li
  &gt;Ruby is a good shell script (Rakefile!),&lt;/li
  &gt;&lt;li
  &gt;Ruby has some file/process handling methods,&lt;/li
  &gt;&lt;li
  &gt;But..&lt;ul
    &gt;&lt;li
      &gt;You couldn't retrieve the output or error of &lt;code
	&gt;system&lt;/code
	&gt;&lt;/li
      &gt;&lt;li
      &gt;You could run a command asynchronously with &lt;code
	&gt;system&lt;/code
	&gt; with &amp;quot;&amp;amp;&amp;quot;, but couldn't kill the process directly&lt;/li
      &gt;&lt;li
      &gt;You couldn't run a command asynchronously with ``&lt;/li
      &gt;&lt;/ul
    &gt;&lt;/li
  &gt;&lt;/ul
&gt;&lt;h2 id="example"
&gt;Example&lt;/h2
&gt;&lt;p
&gt;Start a Sinatra app by a Ruby script and kill the app by the script&lt;/p
&gt;&lt;p
&gt;in shell script:&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;#!/bin/sh
ruby sinatra_app.rb &amp;amp;
PID=$!
# something...
kill $PID
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;in ruby?&lt;/p
&gt;&lt;h2 id="bad-solution"
&gt;Bad solution&lt;/h2
&gt;&lt;pre
&gt;&lt;code
  &gt;system 'ruby sinatra_app &amp;amp;'
&lt;/code
  &gt;&lt;/pre
&gt;&lt;ul
&gt;&lt;li
  &gt;You cannot get the proccess ID, so you cannot kill the process&lt;/li
  &gt;&lt;/ul
&gt;&lt;h2 id="better-solution"
&gt;Better solution&lt;/h2
&gt;&lt;pre
&gt;&lt;code
  &gt;pid = fork do
  exec 'ruby', 'sinatra_app'
end
# something..
Process.kill 'KILL', pid
&lt;/code
  &gt;&lt;/pre
&gt;&lt;ul
&gt;&lt;li
  &gt;This doesn't work on NetBSD4 or Windows due to &lt;code
    &gt;fork()&lt;/code
    &gt;&lt;/li
  &gt;&lt;/ul
&gt;&lt;h2 id="best-solution"
&gt;Best solution&lt;/h2
&gt;&lt;pre
&gt;&lt;code
  &gt;pid = spawn 'ruby', 'sinatra_app'
# something...
Process.kill 'KILL', pid
&lt;/code
  &gt;&lt;/pre
&gt;&lt;ul
&gt;&lt;li
  &gt;&lt;code
    &gt;:)&lt;/code
    &gt;&lt;/li
  &gt;&lt;li
  &gt;&lt;code
    &gt;spawn =~ {fork + exec} or {system + &amp;amp;}&lt;/code
    &gt;&lt;/li
  &gt;&lt;li
  &gt;portable&lt;/li
  &gt;&lt;/ul
&gt;&lt;h2 id="new-system-and-spawn-spec"
&gt;New system and spawn spec&lt;/h2
&gt;&lt;pre
&gt;&lt;code
  &gt;system({'A' =&amp;gt; 'b'}, 'c', in: input_io, [:out, :err] =&amp;gt; :out)
#=&amp;gt; true/false

spawn(...)
#=&amp;gt; Fixnum
&lt;/code
  &gt;&lt;/pre
&gt;&lt;h2 id="even-more.."
&gt;Even more..&lt;/h2
&gt;&lt;p
&gt;&lt;code
  &gt;open3&lt;/code
  &gt; standard library&lt;/p
&gt;&lt;ul
&gt;&lt;li
  &gt;Open3.capture2e&lt;/li
  &gt;&lt;li
  &gt;powered by spawn (read the source!)&lt;/li
  &gt;&lt;/ul
&gt;&lt;h2 id="problem-3"
&gt;Problem 3&lt;/h2
&gt;&lt;ul
&gt;&lt;li
  &gt;&lt;p
    &gt;Local variable shadowing (potantial bug!)&lt;/p
    &gt;&lt;pre
    &gt;&lt;code
      &gt;a = :hello
[1, 2, 3].each do |a|
  p a
end
p a #=&amp;gt; 3 (in 1.8)
&lt;/code
      &gt;&lt;/pre
    &gt;&lt;/li
  &gt;&lt;/ul
&gt;&lt;h2 id="problem-4"
&gt;Problem 4&lt;/h2
&gt;&lt;ul
&gt;&lt;li
  &gt;&amp;quot;Most libraries didn't work&amp;quot;&lt;/li
  &gt;&lt;li
  &gt;Yes it was (particularly on 1.9.1)&lt;/li
  &gt;&lt;/ul
&gt;&lt;h2 id="now"
&gt;now?&lt;/h2
&gt;&lt;p
&gt;Active libraries work for sure!&lt;/p
&gt;&lt;ul
&gt;&lt;li
  &gt;nokogiri&lt;/li
  &gt;&lt;li
  &gt;rails&lt;/li
  &gt;&lt;/ul
&gt;&lt;h2 id="problem-5"
&gt;Problem 5&lt;/h2
&gt;&lt;p
&gt;Installation&lt;/p
&gt;&lt;ul
&gt;&lt;li
  &gt;install ruby, and then install rubygems, ...&lt;/li
  &gt;&lt;/ul
&gt;&lt;h2 id="rubygems-is-builtin"
&gt;rubygems is builtin!&lt;/h2
&gt;&lt;ul
&gt;&lt;li
  &gt;rake as well&lt;/li
  &gt;&lt;/ul
&gt;&lt;h2 id="problem-6"
&gt;Problem 6&lt;/h2
&gt;&lt;p
&gt;Ruby is slow&lt;/p
&gt;&lt;h2 id="yarv"
&gt;YARV!&lt;/h2
&gt;&lt;p
&gt;fib 31&lt;/p
&gt;&lt;ul
&gt;&lt;li
  &gt;1.8.7&lt;ul
    &gt;&lt;li
      &gt;7.99sec&lt;/li
      &gt;&lt;/ul
    &gt;&lt;/li
  &gt;&lt;li
  &gt;1.9.2&lt;ul
    &gt;&lt;li
      &gt;0.64sec&lt;/li
      &gt;&lt;/ul
    &gt;&lt;/li
  &gt;&lt;li
  &gt;(jruby)&lt;ul
    &gt;&lt;li
      &gt;3.00sec&lt;/li
      &gt;&lt;/ul
    &gt;&lt;/li
  &gt;&lt;/ul
&gt;&lt;h2 id="how-to-make-legacy-code-1.9-compatible"
&gt;How to make legacy code 1.9 compatible?&lt;/h2
&gt;&lt;p
&gt;Changes between 1.8 and 1.9&lt;/p
&gt;&lt;ul
&gt;&lt;li
  &gt;String isn't Enumerable&lt;/li
  &gt;&lt;li
  &gt;when clause doesn't accept colon as semicolon&lt;/li
  &gt;&lt;/ul
&gt;&lt;p
&gt;change between 1.9.1 and 1.9.2&lt;/p
&gt;&lt;ul
&gt;&lt;li
  &gt;&lt;code
    &gt;$:&lt;/code
    &gt; doesn't have the current dir.&lt;ul
    &gt;&lt;li
      &gt;&lt;code
	&gt;require_relative&lt;/code
	&gt; is handy (but long...)&lt;/li
      &gt;&lt;/ul
    &gt;&lt;/li
  &gt;&lt;/ul
&gt;&lt;h2 id="demo-make-a-gem-library-1.9.2-compatible"
&gt;Demo: make a gem library 1.9.2 compatible&lt;/h2
&gt;&lt;ul
&gt;&lt;li
  &gt;github gem library&lt;/li
  &gt;&lt;li
  &gt;&lt;code
    &gt;github create&lt;/code
    &gt; etc..&lt;/li
  &gt;&lt;li
  &gt;it's very 1.8 even though it's new&lt;ul
    &gt;&lt;li
      &gt;0.1.0 was March 3, 2008&lt;/li
      &gt;&lt;li
      &gt;0.4.5 was Oct 25, 2010; after 1.9.2 public release!&lt;/li
      &gt;&lt;/ul
    &gt;&lt;/li
  &gt;&lt;/ul
&gt;&lt;h2 id="the-summary-of-this-talk-again"
&gt;The summary of this talk (again)&lt;/h2
&gt;&lt;p
&gt;&amp;quot;Ruby 1.9.2 makes your code cleaner and easier to maintain.&amp;quot;&lt;/p
&gt;&lt;h2 id="end"
&gt;end&lt;/h2
&gt;&lt;p
&gt;&lt;em
  &gt;thanks!&lt;/em
  &gt;&lt;/p
&gt;&lt;p
&gt;by&lt;/p
&gt;&lt;ul
&gt;&lt;li
  &gt;Tatsuhiro Ujihisa&lt;/li
  &gt;&lt;li
  &gt;@ujm&lt;/li
  &gt;&lt;li
  &gt;HootSuite Media, inc&lt;/li
  &gt;&lt;li
  &gt;Ruby, Haskell, JavaScript, Vim script, etc..&lt;/li
  &gt;&lt;/ul
&gt;&lt;p
&gt;&lt;img src="http://twittercism.com/wp-content/uploads/2010/02/hootsuite_icon.png" alt="hootsuite"
   /&gt; hootsuite&lt;/p
&gt;&lt;h2 id="appendix"
&gt;appendix&lt;/h2
&gt;&lt;ul
&gt;&lt;li
  &gt;JRuby&lt;ul
    &gt;&lt;li
      &gt;--1.9 option&lt;/li
      &gt;&lt;li
      &gt;almost compatible with 1.9 except &lt;code
	&gt;spawn()&lt;/code
	&gt; or etc&lt;/li
      &gt;&lt;/ul
    &gt;&lt;/li
  &gt;&lt;/ul
&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-3440809661730784726?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/3440809661730784726/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/11/ruby-192-in-production-with-tatsuhiro.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/3440809661730784726'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/3440809661730784726'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/11/ruby-192-in-production-with-tatsuhiro.html' title='Ruby 1.9.2 in Production with Tatsuhiro Ujihisa'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-5879157954737867939</id><published>2010-11-23T12:59:00.001-08:00</published><updated>2010-11-23T12:59:13.614-08:00</updated><title type='text'>Conditional Operator Associativities</title><content type='html'>&lt;p
&gt;In Ruby:&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;a = true ? :a : true ? :b : :c
p a
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;Guess the answer! Yes, as you thought, the answer is &lt;code
  &gt;:a&lt;/code
  &gt;.&lt;/p
&gt;&lt;p
&gt;In JavaScript:&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;var a = true ? 'a' : true ? 'b' : 'c';
alert(a);
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;Guess the answer! Yes, as you thought, the answer is &lt;code
  &gt;a&lt;/code
  &gt;.&lt;/p
&gt;&lt;p
&gt;In Vim script:&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;let a = 1 ? 'a' : 1 ? 'b' : 'c'
echo a
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;Guess the answer! Yes, as you thought, the answer is &lt;code
  &gt;a&lt;/code
  &gt;.&lt;/p
&gt;&lt;p
&gt;In PHP:&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;$a = true ? 'a' : true ? 'b' : 'c';
print_r($a);
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;Guess the answer! No, the answer if &lt;code
  &gt;&amp;quot;b&amp;quot;&lt;/code
  &gt;.&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;$a = true ? 'a' : (true ? 'b' : 'c');
print_r($a);
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;The code above is the equivalent code to the examples in Ruby, JS and Vim script. It's impossibly difficult to imagine why the specification is so.&lt;/p
&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-5879157954737867939?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/5879157954737867939/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/11/conditional-operator-associativities.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/5879157954737867939'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/5879157954737867939'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/11/conditional-operator-associativities.html' title='Conditional Operator Associativities'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-4735026702791680482</id><published>2010-11-18T18:15:00.001-08:00</published><updated>2010-11-19T11:38:11.884-08:00</updated><title type='text'>Something like closure for Vim script</title><content type='html'>&lt;p
&gt;Vim script doesn't have lambda as a language feature, but you can fake similar thing with the following tricks.&lt;/p
&gt;&lt;p
&gt;When you want to pass a procedure with variables into a function in Vim script, how do you achieve it?&lt;/p
&gt;&lt;p
&gt;Let me explain with other language first, show a well-known function &lt;code
  &gt;map&lt;/code
  &gt;.&lt;/p
&gt;&lt;p
&gt;Ruby(*1):&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;a = 10
p [1, 2, 3].map {|i| i + a }
#=&amp;gt; [11, 12, 13]
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;Python:&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;a = 10
print map(lambda x: x + a, [1, 2, 3])
#=&amp;gt; [11, 12, 13]
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;or more strictly&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;a = 10
def f(x):
    return x + a
print map(f, [1, 2, 3])
#=&amp;gt; [11, 12, 13]
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;On the other hand, Vim script doesn't have such fancy feature but have normal function and dictionary function. The former is like just a global function, scoped globally or file. The latter is like a method which has the concept of &lt;code
  &gt;this&lt;/code
  &gt; of &lt;code
  &gt;self&lt;/code
  &gt; in other languages.&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;let obj = {'a': 10}
function! obj.f(x)
  return a:x + self.a
endfunction

echo obj.f(1)
&amp;quot;=&amp;gt; 11
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;Note that the prefix &lt;code
  &gt;a:&lt;/code
  &gt; means the identifier is an argument of the function.&lt;/p
&gt;&lt;p
&gt;This feature is compatible with lexical scope lambda except for the aspect of the anonymity. But it is very inconvenient that you always have to declare which variables the dictionary function will use.&lt;/p
&gt;&lt;p
&gt;The solution is to use a special variable &lt;code
  &gt;l:&lt;/code
  &gt;.&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;function! Main()
  let a = 10
  let obj = copy(l:)
  function! obj.f(x)
    return a:x + self.a
  endfunction

  echo obj.f(1)
endfunction

call Main()
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;There are three notes for using this trick:&lt;/p
&gt;&lt;ul
&gt;&lt;li
  &gt;&lt;code
    &gt;l:&lt;/code
    &gt; is only available in a function.&lt;/li
  &gt;&lt;li
  &gt;it can cause SEGV if you forget writing &lt;code
    &gt;copy&lt;/code
    &gt;&lt;/li
  &gt;&lt;li
  &gt;&lt;code
    &gt;a:&lt;/code
    &gt; as well if you use not only local variables&lt;/li
  &gt;&lt;/ul
&gt;&lt;h2 id="acknowledge"
&gt;Acknowledge&lt;/h2
&gt;&lt;p
&gt;thinca and tyru taught me this trick for my problem presentation. thinca is using a kind of this trick in &lt;a href="https://github.com/thinca/vim-vparsec"
  &gt;his product.&lt;/a
  &gt;&lt;/p
&gt;&lt;h2 id="footnote"
&gt;Footnote&lt;/h2
&gt;&lt;p
&gt;The following code also works on Ruby.&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;a = 10
f = -&amp;gt;(x) { x + 1 }
p [1, 2, 3].map(&amp;amp;f)
&lt;/code
  &gt;&lt;/pre
&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-4735026702791680482?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/4735026702791680482/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/11/something-like-closure-for-vim-script.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/4735026702791680482'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/4735026702791680482'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/11/something-like-closure-for-vim-script.html' title='Something like closure for Vim script'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-8924945700031581287</id><published>2010-11-12T17:28:00.001-08:00</published><updated>2010-11-13T00:06:58.256-08:00</updated><title type='text'>Memoized recursive fibonacci in Python</title><content type='html'>&lt;p
&gt;A slow literal implementation of fibonacci function in Python is like the below:&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;def fib(n):
    return n if n &amp;lt; 2 else fib(n-2) + fib(n-1)
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;This is slow but you can make it faster with memoize technique, reducing the order.&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;__fib_cache = {}
def fib(n):
    if n in __fib_cache:
        return __fib_cache[n]
    else:
        __fib_cache[n] = n if n &amp;lt; 2 else fib(n-2) + fib(n-1)
        return __fib_cache[n]
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;This is fast, but obviously dirty. Fortunately Python has decorator feature that gives you much better way of writing.&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;def memoize(f):
    cache = {}
    def decorated_function(*args):
        if args in cache:
            return cache[args]
        else:
            cache[args] = f(*args)
            return cache[args]
    return decorated_function

@memoize
def fib(n):
    return n if n &amp;lt; 2 else fib(n-2) + fib(n-1)
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;The &lt;code
  &gt;@memoize&lt;/code
  &gt; decorator is not only for this &lt;code
  &gt;fib()&lt;/code
  &gt; function but also for general purpose. I referred &lt;a href="http://programmingzen.com/2009/05/18/memoization-in-ruby-and-python/"
  &gt;this page&lt;/a
  &gt;. This is succinct and clean.&lt;/p
&gt;&lt;p
&gt;But I felt that the definition of &lt;code
  &gt;memoize()&lt;/code
  &gt;, particularly &lt;code
  &gt;decorated_function()&lt;/code
  &gt;, was too long. If the &lt;code
  &gt;else&lt;/code
  &gt; clause consists of single return statement, you may re-write &lt;code
  &gt;decorated_function()&lt;/code
  &gt; in 1 line.&lt;/p
&gt;&lt;p
&gt;Takeshi Abe &lt;a href="http://twitter.com/fixedpoint_jp/status/2616979487719424"
  &gt;taught&lt;/a
  &gt; me how to make the two lines into one single line.&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;cache[args] = f(*args)
return cache[args]
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;is equivalent to&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;cache.update({args: f(*args)}) or cache[args]
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;So let here is the final version of fib with memoize:&lt;/p
&gt;&lt;pre
&gt;&lt;code
  &gt;def memoize(f):
    cache = {}
    return lambda *args: cache[args] if args in cache else cache.update({args: f(*args)}) or cache[args]

@memoize
def fib(n):
    return n if n &amp;lt; 2 else fib(n-2) + fib(n-1)
&lt;/code
  &gt;&lt;/pre
&gt;&lt;p
&gt;It's fast, short, succinct, and cool.&lt;/p
&gt;&lt;h2 id="footnote"
&gt;Footnote&lt;/h2
&gt;&lt;p
&gt;This approach may be &lt;em
  &gt;against&lt;/em
  &gt; the Python golden way.&lt;/p
&gt;&lt;ul
&gt;&lt;li
  &gt;&lt;a href="http://twitter.com/fixedpoint_jp/status/2622882236600320"
    &gt;http://twitter.com/fixedpoint_jp/status/2622882236600320&lt;/a
    &gt;&lt;/li
  &gt;&lt;li
  &gt;&lt;a href="http://twitter.com/kana1/status/2611298382643200"
    &gt;http://twitter.com/kana1/status/2611298382643200&lt;/a
    &gt;&lt;/li
  &gt;&lt;li
  &gt;&lt;a href="http://twitter.com/kana1/status/2620769314013184"
    &gt;http://twitter.com/kana1/status/2620769314013184&lt;/a
    &gt;&lt;/li
  &gt;&lt;li
  &gt;&lt;a href="http://twitter.com/kana1/status/2622096563769344"
    &gt;http://twitter.com/kana1/status/2622096563769344&lt;/a
    &gt;&lt;/li
  &gt;&lt;/ul
&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-8924945700031581287?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/8924945700031581287/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/11/memoized-recursive-fibonacci-in-python.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/8924945700031581287'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/8924945700031581287'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/11/memoized-recursive-fibonacci-in-python.html' title='Memoized recursive fibonacci in Python'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-1558639110190541055</id><published>2010-11-08T18:46:00.001-08:00</published><updated>2010-11-09T13:14:58.995-08:00</updated><title type='text'>How to make a Unite plugin</title><content type='html'>&lt;h2&gt;Unite&lt;/h2&gt;

&lt;p&gt;The hottest Vim plugin these days is &lt;a href="http://github.com/shougo/unite.vim"&gt;unite.vim&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;:Unite file&lt;/code&gt; command opens a unite dialog that you can specify file names with inputting text.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://gyazo.com/7379f1041084632c66faef9caf3e1f09.png" alt="1" /&gt;&lt;/p&gt;

&lt;p&gt;You can search not only files but also other resources like buffers you've opened.
Unite also allows users to create your own "resource" and to define corresponding actions.&lt;/p&gt;

&lt;p&gt;Here I'll make a demonstrative unite plugin &lt;code&gt;unite-colorscheme&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;colorscheme&lt;/h2&gt;

&lt;p&gt;Vim, particularly GUI version of Vim implementations like MacVim, has &lt;code&gt;colorscheme&lt;/code&gt; that allows you to change the appearance very much. You may change the colorscheme of the Vim just by &lt;code&gt;:colorscheme ujihisa&lt;/code&gt;, but it's not trivial to find which colorschemes you already have. (*1)&lt;/p&gt;

&lt;p&gt;&lt;img src="http://gyazo.com/1bd61185494f53b1d54d6264cc6dc015.png" alt="2" /&gt;&lt;/p&gt;

&lt;h2&gt;unite-colorscheme.vim&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/ujihisa/unite-colorscheme"&gt;https://github.com/ujihisa/unite-colorscheme&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;unite-colorscheme consists of the following two files.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;autoload/unite/sources/colorscheme.vim&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;let s:unite_source = {
      \ 'name': 'colorscheme',
      \ }

function! s:unite_source.gather_candidates(args, context)
  " [(name, dir)]
  " e.g. [('adaryn', '/Users/ujihisa/.vimbundles/ColorSamplerPack/colors'), ...]
  let colorlist = map(split(globpath(&amp;amp;runtimepath, 'colors/*.vim'), '\n'),
      \'[fnamemodify(v:val, ":t:r"), fnamemodify(v:val, ":h")]')

  return map(colorlist, '{
        \ "word": v:val[0],
        \ "source": "colorscheme",
        \ "kind": "colorscheme",
        \ "action__path": printf("%s/%s.vim", v:val[1], v:val[0]),
        \ "action__directory": v:val[1],
        \ }')
endfunction

function! unite#sources#colorscheme#define()
  return s:unite_source
endfunction
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And &lt;code&gt;autoload/unite/kinds/colorscheme.vim&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;let s:kind = {
      \ 'name': 'colorscheme',
      \ 'default_action': 'execute',
      \ 'action_table': {},
      \ 'parents': [],
      \ }
let s:kind.action_table.execute = {
      \ 'is_selectable': 1,
      \ }
function! s:kind.action_table.execute.func(candidates)
  if len(a:candidates) != 1
    echo "candidates must be only one"
    return
  endif
  execute "colorscheme" a:candidates[0].word
endfunction

function! unite#kinds#colorscheme#define()
  return s:kind
endfunction
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;After you installed the plugin, you can search by &lt;code&gt;:Unite colorscheme&lt;/code&gt; and set the colorscheme on the Vim just by selecting one colorscheme from the choice.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://gyazo.com/10090a2afea92a74ff16878e2b129b48.png" alt="3" /&gt;&lt;/p&gt;

&lt;h2&gt;References and footnote&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;(*1) &lt;a href="http://github.com/Shougo/neocomplcache"&gt;neocomplcache.vim&lt;/a&gt; supports colorscheme completion.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/thinca/vim-ref/tree/unite"&gt;vim-ref&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;only the following two files: &lt;a href="https://github.com/thinca/vim-ref/blob/unite/autoload/unite/kinds/ref.vim"&gt;kinds/ref.vim&lt;/a&gt; and &lt;a href="https://github.com/thinca/vim-ref/blob/unite/autoload/unite/sources/ref.vim"&gt;sources/ref.vim&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="http://d.hatena.ne.jp/thinca/20101105/1288896674"&gt;"How to cook a source of Unite (in Japanese)"&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-1558639110190541055?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/1558639110190541055/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/11/how-to-make-unite-plugin.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/1558639110190541055'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/1558639110190541055'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/11/how-to-make-unite-plugin.html' title='How to make a Unite plugin'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-9078736859891632736</id><published>2010-11-07T17:44:00.001-08:00</published><updated>2010-11-07T17:44:40.714-08:00</updated><title type='text'>The Implementation of Enumerable#map of JRuby</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;See &lt;code&gt;src/org/jruby/RubyEnumerable.java&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@JRubyMethod(name = {"map"}, frame = true, compat = CompatVersion.RUBY1_9)
public static IRubyObject map19(ThreadContext context, IRubyObject self, final Block block) {
    return collectCommon19(context, self, block, "map");
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This looks like defining the &lt;code&gt;map19&lt;/code&gt; method with declaring it's the &lt;code&gt;map&lt;/code&gt; method in Ruby, particularly in &lt;code&gt;1.9&lt;/code&gt; mode.
For some reason this is internally &lt;code&gt;collectCommon19()&lt;/code&gt; not &lt;code&gt;mapCommon19()&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;private static IRubyObject collectCommon19(ThreadContext context, IRubyObject self, final Block block, String methodName) {
    final Ruby runtime = context.getRuntime();
    if (block.isGiven()) {
        final RubyArray result = runtime.newArray();

        callEach19(runtime, context, self, new BlockCallback() {
            public IRubyObject call(ThreadContext ctx, IRubyObject[] largs, Block blk) {
                IRubyObject larg = checkArgs(runtime, largs);
                IRubyObject value = block.yield(ctx, larg);
                synchronized (result) {
                    result.append(value);
                }
                return runtime.getNil();
            }
        });
        return result;
    } else {
        return enumeratorize(runtime, self, methodName);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is the definition of &lt;code&gt;collectCommon19&lt;/code&gt;. Focus on the &lt;code&gt;then&lt;/code&gt; clause of the main &lt;code&gt;if&lt;/code&gt; condition block.
It's basically calling &lt;code&gt;callEach19()&lt;/code&gt; with an instance of BlockCallback, redefining &lt;code&gt;call()&lt;/code&gt;. This looks like block-passing style in Ruby.&lt;/p&gt;

&lt;p&gt;Focus also on the line just before the &lt;code&gt;callEach19()&lt;/code&gt;. The variable &lt;code&gt;result&lt;/code&gt; looks like an empty Ruby array for storing values in &lt;code&gt;map&lt;/code&gt; process. The definition of the method &lt;code&gt;newArray()&lt;/code&gt; is the following.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public RubyArray newArray() {
    return RubyArray.newArray(this);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;OK. How about &lt;code&gt;RubyArray.newArray()&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/** rb_ary_new
 *
 */
public static final RubyArray newArray(final Ruby runtime) {
    return newArray(runtime, ARRAY_DEFAULT_SIZE);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ok, next. Note that the constant &lt;code&gt;ARRAY_DEFAULT_SIZE&lt;/code&gt; is an int value.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public static final RubyArray newArray(final Ruby runtime, final int len) {
    RubyArray array = new RubyArray(runtime, len);
    RuntimeHelpers.fillNil(array.values, 0, array.values.length, runtime);
    return array;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Looks like &lt;code&gt;[0, ..., 0]&lt;/code&gt; with size ARRAY_DEFAULT_SIZE. So you may wonder is it OK to define a longer array if the receiver of &lt;code&gt;map&lt;/code&gt; has longer size than &lt;code&gt;ARRAY_DEFAULT_SIZE&lt;/code&gt;? I also wonder.&lt;/p&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-9078736859891632736?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/9078736859891632736/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/11/implementation-of-enumerablemap-of.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/9078736859891632736'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/9078736859891632736'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/11/implementation-of-enumerablemap-of.html' title='The Implementation of Enumerable#map of JRuby'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-5248886852140597459</id><published>2010-11-05T16:57:00.001-07:00</published><updated>2010-11-05T16:57:44.862-07:00</updated><title type='text'>The Problem and Solution of Haml</title><content type='html'>&lt;p&gt;When I write an HTML file I always write in Haml first and generate HTML by &lt;code&gt;haml&lt;/code&gt; command. Haml is so handy that Haml makes us free from writing closing tags like &lt;code&gt;&amp;lt;/p&amp;gt;&lt;/code&gt;.
The problem in Haml is that it is very difficult to type &lt;code&gt;%&lt;/code&gt; very often. The symbol is the second most difficult location (*1) in a keyboard.&lt;/p&gt;

&lt;p&gt;The solution is to write the following code on you &lt;code&gt;~/.vim/ftplugin/haml.vim&lt;/code&gt; which let &lt;code&gt;:&lt;/code&gt; key as &lt;code&gt;%&lt;/code&gt; only in Haml file and when the cursor is on the top of the line.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;inoremap &amp;lt;buffer&amp;gt;&amp;lt;expr&amp;gt; : &amp;lt;SID&amp;gt;on_the_top() ? '%' : ':'
function! s:on_the_top()
  return col('.') == 1 || getline(line('.'))[0:col('.')] =~ '^\s*$'
endfunction
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that I swapped &lt;code&gt;:&lt;/code&gt; and &lt;code&gt;;&lt;/code&gt;. If you didn't swap them, just to swap your keyboard or the code.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;(*1) The most difficult location key is &lt;code&gt;^&lt;/code&gt; (shift + 6). If you want to make a programming language which is highly difficult to code, use &lt;code&gt;^&lt;/code&gt; a lot.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-5248886852140597459?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/5248886852140597459/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/11/problem-and-solution-of-haml.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/5248886852140597459'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/5248886852140597459'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/11/problem-and-solution-of-haml.html' title='The Problem and Solution of Haml'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-8787792860350266801</id><published>2010-10-31T13:30:00.001-07:00</published><updated>2010-10-31T13:30:08.282-07:00</updated><title type='text'>List of Vim plugins this computer has</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;Most of Vim plugins I'm using is controlled under &lt;code&gt;pathogen&lt;/code&gt; until the day &lt;code&gt;VimJolts&lt;/code&gt; will be released.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ColorSamplerPack

&lt;ul&gt;
&lt;li&gt;A collection of colorschemes. I use &lt;code&gt;zenburn&lt;/code&gt; in this collection or &lt;code&gt;mrkn256&lt;/code&gt; not in this collection.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;IndentAnything

&lt;ul&gt;
&lt;li&gt;Only for JavaScript indentation Support.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;blogger.vim

&lt;ul&gt;
&lt;li&gt;For blogging. Written by me.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;camelcasemotion

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;,w&lt;/code&gt; as "go to the next capital character."&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;ghc_complete

&lt;ul&gt;
&lt;li&gt;A neocomplcache plugin for ghc.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;gist-vim

&lt;ul&gt;
&lt;li&gt;To post the current buffer to gist.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;git-vim

&lt;ul&gt;
&lt;li&gt;To commit the current file or to view git diff.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;hootsuite

&lt;ul&gt;
&lt;li&gt;For HootSuite development.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;indent-haskell.vim

&lt;ul&gt;
&lt;li&gt;An indent file for Haskell.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;neocomplcache

&lt;ul&gt;
&lt;li&gt;The ultimate auto complete tool.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;quickrun

&lt;ul&gt;
&lt;li&gt;The ultimate quick running tool.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;repl.vim

&lt;ul&gt;
&lt;li&gt;To start repl in Ruby, Erlang and Haskell. Written by me.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;shadow.vim

&lt;ul&gt;
&lt;li&gt;The ultimate file-shadowing tool.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;stickykey.vim

&lt;ul&gt;
&lt;li&gt;To emulate normal keys as modifier keys.&lt;/li&gt;
&lt;li&gt;I use this for CoffeeScript trick. &lt;a href='http://vim-users.jp/2010/07/hack164/'&gt;http://vim-users.jp/2010/07/hack164/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;thinca-poslist

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;amp;lt;C-o&amp;amp;gt;&lt;/code&gt; can go back at any movements including &lt;code&gt;j&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;uj-textile

&lt;ul&gt;
&lt;li&gt;ftdetect, ftplugin and syntax file for textile.&lt;/li&gt;
&lt;li&gt;I suppose this plugin is written by someone. I wonder why this dir name contains &lt;code&gt;uj&lt;/code&gt; prefix...&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;unite.vim

&lt;ul&gt;
&lt;li&gt;Anything.el&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;vim-altercmd

&lt;ul&gt;
&lt;li&gt;Automatically capitalize a Vim command in cmdwin&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;vim-coffee-script

&lt;ul&gt;
&lt;li&gt;ftdetect, ftplugin, indent and syntax file for CoffeeScript.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;vim-markdown

&lt;ul&gt;
&lt;li&gt;ftdetect, ftplugin and syntax file for Markdown.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;vim-smartchr-0.1.0

&lt;ul&gt;
&lt;li&gt;My mappings in vimrc is full of the flavor of smartchr.&lt;/li&gt;
&lt;li&gt;My favorite plugin.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;vim-smartword-0.0.2

&lt;ul&gt;
&lt;li&gt;An extention of &lt;code&gt;w&lt;/code&gt; or &lt;code&gt;e&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;vim-surround

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;cs([&lt;/code&gt; changes the parenthes into brackets.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;vim-textobj-indent-0.0.3

&lt;ul&gt;
&lt;li&gt;You can select by indentation.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;vim-textobj-user-0.3.8

&lt;ul&gt;
&lt;li&gt;You can define your own textobj easily.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;vimclojure-2.1.2

&lt;ul&gt;
&lt;li&gt;A lot of supports for clojure including ftdetect, ftplugin, index and syntax.&lt;/li&gt;
&lt;li&gt;This has repl support but I've never used it so far.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;vimproc

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;:!&lt;/code&gt;, &lt;code&gt;:r!&lt;/code&gt; and &lt;code&gt;system()&lt;/code&gt; substitutor.&lt;/li&gt;
&lt;li&gt;This is used by quickrun, repl.vim, vimshell and &lt;code&gt;.vimrc&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;vimshell

&lt;ul&gt;
&lt;li&gt;A shell for vim.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Syntax files&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;gas

&lt;ul&gt;
&lt;li&gt;for Gnu Assembly language.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;haskell.vim&lt;/li&gt;
&lt;li&gt;rdoc.vim

&lt;ul&gt;
&lt;li&gt;obviously&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Obsolete files&lt;/h2&gt;

&lt;p&gt;This blog post helped me finding some obsolete plugins that I should throw away.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;shim

&lt;ul&gt;
&lt;li&gt;An interactive Haskell shell in Vim.&lt;/li&gt;
&lt;li&gt;repl.vim is a superset of this plugin.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;hints_man2

&lt;ul&gt;
&lt;li&gt;?&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-8787792860350266801?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/8787792860350266801/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/10/list-of-vim-plugins-this-computer-has.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/8787792860350266801'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/8787792860350266801'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/10/list-of-vim-plugins-this-computer-has.html' title='List of Vim plugins this computer has'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-7300065655958874089</id><published>2010-10-27T18:28:00.001-07:00</published><updated>2010-10-27T18:28:54.787-07:00</updated><title type='text'>Is Hash Comment in SQL?</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;A "&lt;code&gt;#&lt;/code&gt;" is not the character to start a comment in SQL, but "&lt;code&gt;--&lt;/code&gt;" is.&lt;/p&gt;

&lt;p&gt;A "&lt;code&gt;#&lt;/code&gt;" is the character &lt;em&gt;to the end of the line&lt;/em&gt; in &lt;em&gt;MySQL&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;If you are a Vimmer and only use MySQL when you edit &lt;code&gt;.sql&lt;/code&gt; files, you may want to regard the characters after &lt;code&gt;#&lt;/code&gt;. &lt;code&gt;.sql&lt;/code&gt; files are regarded as just SQL in Vim, but you can specify them as MySQL. Just to write the following one line on &lt;code&gt;~/.vim/ftdetect/mysql.vim&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;autocmd BufRead,BufNewFile *.sql set filetype=mysql
&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-7300065655958874089?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/7300065655958874089/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/10/is-hash-comment-in-sql.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/7300065655958874089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/7300065655958874089'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/10/is-hash-comment-in-sql.html' title='Is Hash Comment in SQL?'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-302254877340041657</id><published>2010-10-21T10:02:00.001-07:00</published><updated>2010-10-22T16:41:28.301-07:00</updated><title type='text'>Reading Git Log In Kindle</title><content type='html'>&lt;p&gt;I bought a kindle last week and realized how awesome it was.&lt;/p&gt;

&lt;p&gt;By the way most programmers' work begins with reading &lt;code&gt;git-log&lt;/code&gt;
before they start writing great codes. If you can read it with your
kindle, having fantastic coffee, it should be amazing experience.&lt;/p&gt;

&lt;h2&gt;How to do that&lt;/h2&gt;

&lt;p&gt;The git log after you git pull with time ascending order is
available with the following command (*1).&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git log HEAD@{1}..HEAD --reverse
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can read the diffs as well, with &lt;code&gt;-u&lt;/code&gt; option.&lt;/p&gt;

&lt;p&gt;About coloring. Vim has diff syntax coloring system and can
generate an html file with the color.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git log -u HEAD@{1}..HEAD --reverse | vim - -c 'TOhtml' -c 'w | qa!'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This generates &lt;code&gt;Untitled.html&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ open ./Untitled.html
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open Print dialog in your safari&lt;/li&gt;
&lt;li&gt;Save PDF&lt;/li&gt;
&lt;li&gt;Send the file to Kindle&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;That's it. Enjoy!&lt;/p&gt;

&lt;h2&gt;References&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;*1 &lt;a href="http://d.hatena.ne.jp/thinca/20100713/1278952492"&gt;http://d.hatena.ne.jp/thinca/20100713/1278952492&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://vim-users.jp/2010/04/hack140/"&gt;http://vim-users.jp/2010/04/hack140/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-302254877340041657?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/302254877340041657/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/10/reading-git-log-in-kindle.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/302254877340041657'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/302254877340041657'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/10/reading-git-log-in-kindle.html' title='Reading Git Log In Kindle'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-4911266002048338168</id><published>2010-10-13T21:40:00.001-07:00</published><updated>2010-11-02T17:16:35.124-07:00</updated><title type='text'>A Java Library Looks Like A JRuby Library</title><content type='html'>&lt;h2&gt;Problem&lt;/h2&gt;

&lt;p&gt;In the article I wrote,
&lt;a href="http://ujihisa.blogspot.com/2010/06/introduction-to-jruby-bidirectional.html"&gt;Introduction to JRuby - Bidirectional Communication&lt;/a&gt;,
I described how to define a class in Java and call it in JRuby. The
class written in Java is called by JRuby in a different way to a
library written in pure ruby.&lt;/p&gt;

&lt;p&gt;For example, assuming now you are making a Ruby library that has a
class and a singleton method &lt;code&gt;Hamburger.arrayze&lt;/code&gt;. If it's in Ruby
you can write a single rb file &lt;code&gt;hamburger.rb&lt;/code&gt; and write the
following code.&lt;/p&gt;

&lt;p&gt;hamburger.rb:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Hamburger
  def self.arrayze(x)
    ['begin', x, 'end']
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and call it from another rb file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'hamburger'
p Hamburger.arrayze('hello')
#=&amp;gt; ["begin", "hello", "end"]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You also can implement Hamburger class in pure Java.&lt;/p&gt;

&lt;p&gt;Hamburger.java:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Hamburger {
  static public String[] arrayze(String x) {
    String[] memo = {"begin", x, "end"};
    return memo;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Compile it into a jar file.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ javac Hamburger.java
$ jar cf hamburger.jar Hamburger.class
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then call the library from an rb file.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'hamburger.jar'
include_class Java::Hamburger

p Hamburger.arrayze('hello').to_a
#=&amp;gt; ["begin", "hello", "end"]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The result ran on JRuby is exactly same to the previous one, but
the code is very different. You cannot delete &lt;code&gt;.jar&lt;/code&gt; extension in
&lt;code&gt;require&lt;/code&gt; method, abbreviate the &lt;code&gt;include_class&lt;/code&gt; declaration, or
&lt;code&gt;.to_a&lt;/code&gt; to convert Java class Object to Ruby Array of
String.&lt;/p&gt;

&lt;h2&gt;Solution 1&lt;/h2&gt;

&lt;p&gt;First we should not to return a Java object but to return a Ruby array.&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-4911266002048338168?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/4911266002048338168/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/10/java-library-looks-like-jruby-library.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/4911266002048338168'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/4911266002048338168'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/10/java-library-looks-like-jruby-library.html' title='A Java Library Looks Like A JRuby Library'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-848257298788272632</id><published>2010-10-13T20:16:00.001-07:00</published><updated>2010-10-19T12:06:29.897-07:00</updated><title type='text'>Git-SVN Low-Risk Practice</title><content type='html'>&lt;h2&gt;Assumptions&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;You are supposed to work on a svn branch &lt;code&gt;topic&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;You hate svn.&lt;/li&gt;
&lt;li&gt;You want to follow changes of svn trunk.&lt;/li&gt;
&lt;li&gt;You hate the merging in svn.&lt;/li&gt;
&lt;li&gt;You already checked out the svn repository with git-svn-clone
with stdlayout option.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Wrong way&lt;/h2&gt;

&lt;p&gt;First you make a local git branch &lt;code&gt;topic&lt;/code&gt; that'll sync with svn
branch &lt;code&gt;topic&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git checkout -b topic topic
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then you work on the branch, including &lt;code&gt;git-commit&lt;/code&gt; a lot. Before
you go home you push the changes into the main svn repository by
&lt;code&gt;git-svn-dcommit&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You sometimes have to see the changes in trunk.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git checkout master
$ git svn rebase
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And merges the changes into your topic branch.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git checkout topic
$ git merge --no-ff master
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You know that merge without &lt;code&gt;--no-ff&lt;/code&gt; option breaks git-svn system
so you did &lt;code&gt;--no-ff&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Finally you finished all your work on the topic branch and tried to
merge the changes into trunk.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git checkout master
$ git merge --no-ff topic
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That causes a lot of conflicts that you have to resolve manually.&lt;/p&gt;

&lt;h2&gt;Right way&lt;/h2&gt;

&lt;p&gt;The "Wrong way" example had two failures.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ambiguous name of topic&lt;/li&gt;
&lt;li&gt;merge from trunk to topic&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;The first one is not fatal but annoying. Every time you run a git
command with specifying a branch name shows a warning message that
your local git branch name is ambiguous. You should have make a
local git branch in which name is different to the svn branch.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git checkout -b tpc topic
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Next. You are not supposed to merge changes in trunk to topic
branch that will be merged to trunk. That causes a lot of
conflicts.&lt;/p&gt;

&lt;p&gt;The solution is that you create another local git branch that
doesn't sync svn branch directly.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git checkout -b t tpc
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Instead of trying to merge from master to t, try to rebase from
master to t. Regard the tpc branch for very temporary one.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git checkout master
$ git svn rebase
$ git checkout t
$ git rebase master

$ git checkout tpc
$ git svn dcommit
$ svn delete `git svn info --url`
$ git checkout t
$ git branch -d -r topic
$ git branch -D tpc
$ git svn branch topic
$ git checkout -b tpc topic
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;img src="http://img.f.hatena.ne.jp/images/fotolife/u/ujihisa/20101014/20101014121445.png?1287026116" alt="figure 1" /&gt;&lt;/p&gt;

&lt;p&gt;Note that this approach make the svn repository log messy. Be
resigned; that's the subversion.&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-848257298788272632?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/848257298788272632/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/10/git-svn-low-risk-practice.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/848257298788272632'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/848257298788272632'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/10/git-svn-low-risk-practice.html' title='Git-SVN Low-Risk Practice'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-4411178775498703796</id><published>2010-09-07T19:48:00.001-07:00</published><updated>2010-09-08T17:50:49.785-07:00</updated><title type='text'>RSpec for Java</title><content type='html'>&lt;p&gt;I think the reasons why people are using Java are in the following
list.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The product must run on JVM&lt;/li&gt;
&lt;li&gt;You are fixing existing code that is written in Java&lt;/li&gt;
&lt;li&gt;You or your co-workers love Java&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Java has some testing frameworks written in Java, but it's
difficult to implement something like RSpec due to the limitation
of Java syntax. But actually you don't have to use a testing
framework in Java but can use RSpec on JRuby, even though the
product is not using JRuby.&lt;/p&gt;

&lt;h2&gt;A minimum example&lt;/h2&gt;

&lt;p&gt;Hello.java&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class Hello {
  public String world() {
    return "world!";
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;hello_spec.rb&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'java'
java_import 'Hello'

describe 'Hello' do
  it 'world' do
    Hello.new.world.should == 'world!'
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Compile Hello.java and run RSpec command.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ javac Hello.java
$ jruby -S spec hello_spec.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This works.&lt;/p&gt;

&lt;p&gt;If you didn't install RSpec yet, you can install it with the
following command.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ jruby -S gem install rspec
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;A bit complex example&lt;/h2&gt;

&lt;p&gt;This approach is powerful; you can use a Java bytecode which was
compiled with some special parameters like &lt;code&gt;-target&lt;/code&gt;. For example,
J2ME programs needs to be compiled as Java 1.4 and needs a jar file
as well. You still can spec such program.&lt;/p&gt;

&lt;p&gt;A.java&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;import javax.microedition.midlet.MIDlet;

class A extends MIDlet {
  public void destroyApp(boolean unconditional) {
    notifyDestroyed();
  }
  protected void pauseApp() {
  }
  protected void startApp() {
  }
  static public String f() {
    return "sajdfksadfsd";
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;a_spec.rb&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'java'
java_import 'A'

describe 'A.f' do
  it 'is on java' do
    RUBY_DESCRIPTION.should be_include 'jruby'
  end

  it 'is a strange string' do
    A.f.should == 'sajdfksadfsd'
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;run&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ javac -target 1.4 -source 1.4 -g:none -bootclasspath the-jar-file.jar A.java
$ jruby -J-cp the-jar-file.jar:. -S ~/git/jruby/bin/spec a_spec.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It works.&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-4411178775498703796?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/4411178775498703796/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/09/rspec-for-java.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/4411178775498703796'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/4411178775498703796'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/09/rspec-for-java.html' title='RSpec for Java'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-8142349882052652368</id><published>2010-09-05T19:32:00.001-07:00</published><updated>2010-09-05T19:32:33.909-07:00</updated><title type='text'>Shows Message Immediately in Haskell</title><content type='html'>&lt;p&gt;You've seen such a prompt very often.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;OK? [y/n]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Your cursor is just after the prompt with 1 space. If you type &lt;code&gt;y&lt;/code&gt; the process will continue and if you type any other characters, not only &lt;code&gt;n&lt;/code&gt;, the process will stop. This is easy to implement in Ruby.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;print &amp;quot;OK? [y/n] &amp;quot;
if gets.chars.first == 'y'
  puts 'go go go'
else
  puts 'nooo'
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It seems to be easy for Haskell beginners to implement it in Haskell like the following code.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;main = do putStr &amp;quot;OK? [y/n] &amp;quot;
          s &amp;lt;- getLine
          case (head s) of
               'y' -&amp;gt; putStrLn &amp;quot;Nice&amp;quot;
               otherwise -&amp;gt; putStrLn &amp;quot;omg&amp;quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But it doesn't work appropriately due to &lt;code&gt;stdout&lt;/code&gt; buffering. Haskell has &lt;code&gt;IO&lt;/code&gt; library that can control buffering. Add &lt;code&gt;hFlush stdout&lt;/code&gt; after importing the library.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;import IO (hFlush, stdout)

main = do putStr &amp;quot;OK? [y/n] &amp;quot;
          hFlush stdout
          s &amp;lt;- getLine
          case (head s) of
               'y' -&amp;gt; putStrLn &amp;quot;Nice&amp;quot;
               otherwise -&amp;gt; putStrLn &amp;quot;omg&amp;quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This works.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-8142349882052652368?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/8142349882052652368/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/09/shows-message-immediately-in-haskell.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/8142349882052652368'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/8142349882052652368'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/09/shows-message-immediately-in-haskell.html' title='Shows Message Immediately in Haskell'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-3847801844976668418</id><published>2010-08-16T20:38:00.001-07:00</published><updated>2010-08-16T20:38:43.313-07:00</updated><title type='text'>Regular Expression Benchmarks</title><content type='html'>&lt;p&gt;Most modern programming languages have regular expression engines. Here I'll compare the speed of each regular expression engines with long text matching which has backtracking. I used Ruby, Perl and Python for this examination.&lt;/p&gt;

&lt;h2&gt;A time-consuming regular expression example&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;/(aa)*aa/ =~ 'aa'&lt;/code&gt; needs backtracking. The longer the length is, the longer it would take. Let &lt;code&gt;m&lt;/code&gt; as the length of the characters and &lt;code&gt;n&lt;/code&gt; as the number of repeat. For example the case when &lt;code&gt;n = 2&lt;/code&gt; and &lt;code&gt;m = 3&lt;/code&gt; is&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/(aa)*aa(bb)*bb(cc)*cc/ =~ 'aabbcc'
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Codes&lt;/h2&gt;

&lt;p&gt;Ruby:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def time
  t = Time.now
  yield
  Time.now - t
end

def ryutorion(m, n)
  chars = (0...n).map {|i| ('a'.ord + i % 26).chr }
  regex = Regexp.new chars.map {|c| &amp;quot;(#{c*m})*#{c*m}&amp;quot; }.join
  str = chars.map {|c| c*m }.join
  time { regex =~ str }
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Python:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;import re
import time

def timeof(f):
    t = time.time()
    f()
    return time.time() - t

def ryutorion(m, n):
    chars = [ chr(ord('a') + i % 26) for i in range(n) ]
    regex = re.compile(''.join([ '(' + c*m + ')*' + c*m for c in chars ]))
    str = ''.join([ c*m for c in chars ])
    return timeof(lambda: regex.match(str))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Perl:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;use warnings;
use strict;
use Time::HiRes qw(gettimeofday tv_interval);

sub gen_regex {
    my ($m, $n) = @_;

    join &amp;quot;&amp;quot;, map { 
        my $s = chr(ord('a') + ($_ % 26)) x $m;
        &amp;quot;($s)*$s&amp;quot;
    } (0 .. $n - 1);
}

sub gen_input {
    my ($m, $n) = @_;

    join &amp;quot;&amp;quot;, map { chr(ord('a') + ($_ % 26)) x $m } (0 .. $n - 1);
}

my $r = gen_regex 1, 1;
my $i = gen_input 1, 1;
$r = qr/$r/;
my $ts = [gettimeofday];
my $te = [gettimeofday] if($i =~ /$r/);
my $elapsed = tv_interval $ts, $te;
print &amp;quot;$elapsed\n&amp;quot;;

for my $N (10, 20) {
    for my $M (10000, 20000) {
        $r = gen_regex $M, $N;
        $i = gen_input $M, $N;
        $r = qr/$r/;
        $ts = [gettimeofday];
        $te = [gettimeofday] if($i =~ /$r/);
        $elapsed = tv_interval $ts, $te;
        print &amp;quot;$elapsed\n&amp;quot;;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This perl example was written by &lt;a href="http://twitter.com/ryutorion"&gt;Masahiro Kimoto&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Result&lt;/h2&gt;

&lt;p&gt;shorter test: &lt;code&gt;n = {10000, 20000}&lt;/code&gt; = &lt;code&gt;m = {10, 20}&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Ruby&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;p ryutorion(10000, 10) #=&amp;gt; 0.000278
p ryutorion(20000, 10) #=&amp;gt; 0.000698
p ryutorion(10000, 20) #=&amp;gt; 0.000538
p ryutorion(20000, 20) #=&amp;gt; 0.001026
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Python&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;print ryutorion(10000, 10) #=&amp;gt; 0.00126099586487
print ryutorion(20000, 10) #=&amp;gt; 0.00168895721436
print ryutorion(10000, 20) #=&amp;gt; 0.00180792808533
print ryutorion(20000, 20) #=&amp;gt; 0.00338697433472
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Perl&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;($M = 10000, $N = 10) #=&amp;gt; 0.000066
($M = 20000, $N = 10) #=&amp;gt; 0.000185
($M = 10000, $N = 20) #=&amp;gt; 0.000163
($M = 20000, $N = 20) #=&amp;gt; 0.000294
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;longer test: &lt;code&gt;n = {10000, 20000}&lt;/code&gt; = &lt;code&gt;m = {100, 200}&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Ruby (ruby 1.9.2)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;0.002721
0.00672
0.005441
0.013364
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Python (python 2.7)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Traceback (most recent call last):
  File &amp;quot;a.py&amp;quot;, line 16, in &amp;lt;module&amp;gt;
    print ryutorion(10000, 100)
  File &amp;quot;a.py&amp;quot;, line 11, in ryutorion
    regex = re.compile(''.join([ '(' + c*m + ')*' + c*m for c in chars ]))
  File &amp;quot;/usr/local/Cellar/python/2.7/lib/python2.7/re.py&amp;quot;, line 190, in compile
    return _compile(pattern, flags)
  File &amp;quot;/usr/local/Cellar/python/2.7/lib/python2.7/re.py&amp;quot;, line 243, in _compile
    p = sre_compile.compile(pattern, flags)
  File &amp;quot;/usr/local/Cellar/python/2.7/lib/python2.7/sre_compile.py&amp;quot;, line 511, in compile
    &amp;quot;sorry, but this version only supports 100 named groups&amp;quot;
AssertionError: sorry, but this version only supports 100 named groups
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Perl (perl 5.10.0)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;0.000981
0.00269
0.004181
0.005484
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;Perl is the strongest. Use Perl.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-3847801844976668418?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/3847801844976668418/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/08/regular-expression-benchmarks.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/3847801844976668418'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/3847801844976668418'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/08/regular-expression-benchmarks.html' title='Regular Expression Benchmarks'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-5206354584171634375</id><published>2010-08-15T13:37:00.001-07:00</published><updated>2010-08-15T13:38:15.867-07:00</updated><title type='text'>Haskell liftM practice</title><content type='html'>&lt;h2&gt;with lists&lt;/h2&gt;

&lt;p&gt;I was trying to remember how to use Haskell. This blog post focuses only on &lt;code&gt;Control.Monad.liftM&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;The type of &lt;code&gt;liftM&lt;/code&gt; is &lt;code&gt;(Monad m) =&amp;gt; (a1 -&amp;gt; r) -&amp;gt; m a1 -&amp;gt; m r&lt;/code&gt; which evaluates the second argument with the first argument as if it's in do block.&lt;/p&gt;

&lt;p&gt;Let me explain that with the following example. You need the list of the values which each of them are three times bigger than the original list [1, 2, 3]. The most straightforward way in Haskell is to use list comprehension.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[ x * 3 | x &amp;lt;- [1, 2, 3]]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;List Comprehension is just a syntactic sugar of List Monad. The code is equivalent to the following code.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;do x &amp;lt;- [1, 2, 3]
   return $ x * 3
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Do notation is just a syntactic sugar of List Monad as well.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[1, 2, 3] &amp;gt;&amp;gt;= \x -&amp;gt; return (x * 3)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You also can make the code simpler with point free style.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[1, 2, 3] &amp;gt;&amp;gt;= return . (* 3)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now it's time to use &lt;code&gt;liftM&lt;/code&gt;. You can write the code with &lt;code&gt;liftM&lt;/code&gt; in the following way.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;liftM (* 3) [1, 2, 3]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is the simplest. Note that you have to declare &lt;code&gt;import Control.Monad&lt;/code&gt; to use &lt;code&gt;liftM&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;with Parsec&lt;/h2&gt;

&lt;p&gt;The code below is from &lt;a href="http://jonathan.tang.name/files/scheme_in_48/"&gt;Write Yourself a Scheme in 48 Hours&lt;/a&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;parseNumber = liftM (Number . read) $ many1 digit
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I rewrite it without &lt;code&gt;liftM&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;parseNumber = do x &amp;lt;- many1 digit
                 return $ Number $ read x
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;parseNumber = do x &amp;lt;- many1 digit
                 return $ (Number . read) x
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;parseNumber = many1 digit &amp;gt;&amp;gt;= \x -&amp;gt; return $ (Number . read) x
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;parseNumber = many1 digit &amp;gt;&amp;gt;= \x -&amp;gt; (return . Number . read) x
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;parseNumber = many1 digit &amp;gt;&amp;gt;= return $ Number . read
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;summary&lt;/h2&gt;

&lt;p&gt;Using &lt;code&gt;liftM&lt;/code&gt; can make code simpler and easier to understand with its natural order of arguments.&lt;/p&gt;

&lt;p&gt;The most difficult thing for using &lt;code&gt;liftM&lt;/code&gt; is to write the correct spelling of &lt;code&gt;liftM&lt;/code&gt;. I cannot remember how many times I wrote &lt;code&gt;listM&lt;/code&gt; instead of &lt;code&gt;liftM&lt;/code&gt;. It is very difficult and fatal issue.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-5206354584171634375?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/5206354584171634375/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/08/haskell-liftm-practice.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/5206354584171634375'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/5206354584171634375'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/08/haskell-liftm-practice.html' title='Haskell liftM practice'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-5581081115713561011</id><published>2010-07-15T21:14:00.001-07:00</published><updated>2010-07-17T13:29:03.206-07:00</updated><title type='text'>Combining Java, Clojure and JRuby</title><content type='html'>&lt;p&gt;JRuby can access classes implemented in pure Java code. Clojure can
generate a class file. Therefore it's straightforward for JRuby to
access classes implemented in Clojure.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://gyazo.com/0b05b7637f2c249e20a687d209323fe6.png" alt="relationship" /&gt;&lt;/p&gt;

&lt;p&gt;First I define a class with a method in plain Java.&lt;/p&gt;

&lt;p&gt;MrJava.java:&lt;/p&gt;

&lt;script src='http://gist.github.com/477914.js?file=gistfile1.txt'/&gt;

&lt;p&gt;and compile it.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ javac MrJava.java
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now you have MrJava.class.&lt;/p&gt;

&lt;p&gt;Next I defina class with a method in Clojure.&lt;/p&gt;

&lt;p&gt;MsClojure.clj:&lt;/p&gt;

&lt;script src='http://gist.github.com/477915.js?file=gistfile1.txt'/&gt;

&lt;p&gt;This is almost equivalent to the previous code. Try compiling it.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ java -cp ~/git/clojure/clojure.jar:. clojure.main -e &amp;quot;(compile 'MsClojure)&amp;quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that you specified your own clojure.jar. Nou you have
&lt;code&gt;classes/MsClojure.class&lt;/code&gt;... not &lt;code&gt;./MsClojure.class&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Try combining them with JRuby!&lt;/p&gt;

&lt;p&gt;a.rb:&lt;/p&gt;

&lt;script src='http://gist.github.com/477916.js?file=gistfile1.txt'/&gt;

&lt;p&gt;and run by:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ jruby -J-cp ~/git/clojure/clojure.jar:classes:.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;then you will get the following message.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Good afternoon Ujihisa, how are you?
Hey Ujihisa!
&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
&lt;li&gt;It doesn't change &lt;code&gt;$: &amp;lt;&amp;lt; '~/git/clojure/clojure.jar'&lt;/code&gt; in
JRuby file. You have to give classpath by command line option.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;References&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://clojure.org/compilation"&gt;http://clojure.org/compilation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-5581081115713561011?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/5581081115713561011/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/07/combining-java-clojure-and-jruby.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/5581081115713561011'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/5581081115713561011'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/07/combining-java-clojure-and-jruby.html' title='Combining Java, Clojure and JRuby'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-1729785199495848607</id><published>2010-07-11T13:05:00.001-07:00</published><updated>2010-07-11T13:05:01.289-07:00</updated><title type='text'>Dynamic OO Codes</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;I posted &lt;a href='http://gist.github.com/463974'&gt;this code snippet&lt;/a&gt; in Twitter to get responses. I wrote the original code in Ruby, and others wrote ones in Perl and Haskell. Others and I also tried to write ones in Java and C++, but failed. I also wrote it in CoffeeScript.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Perl &lt;a href='http://gist.github.com/463980'&gt;http://gist.github.com/463980&lt;/a&gt; by sartak&lt;/li&gt;
&lt;li&gt;Haskell &lt;a href='http://gist.github.com/464078'&gt;http://gist.github.com/464078&lt;/a&gt; by eagletmt&lt;/li&gt;
&lt;li&gt;CoffeeScript &lt;a href='http://gist.github.com/471778'&gt;http://gist.github.com/471778&lt;/a&gt; by ujihisa&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If anyone tried this challenge, please &lt;a href='http://twitter.com/ujm'&gt;let me know&lt;/a&gt;.
For example I didn't get responses in Lisp family languages.&lt;/p&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-1729785199495848607?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/1729785199495848607/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/07/dynamic-oo-codes.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/1729785199495848607'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/1729785199495848607'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/07/dynamic-oo-codes.html' title='Dynamic OO Codes'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-8580416276416279735</id><published>2010-07-10T16:47:00.001-07:00</published><updated>2010-07-10T16:47:17.461-07:00</updated><title type='text'>JavaScript tricks in Ruby</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;I attended a JavaScript workshop in Vancouver today and the talk by &lt;a href='http://ejohn.org/'&gt;John Resig&lt;/a&gt; was inspiring. I pick up some notices here.
&lt;a href='http://www.meetup.com/vancouver-javascript-developers/calendar/13867715/?a=cr1p_grp&amp;amp;amp;rv=cr1p'&gt;http://www.meetup.com/vancouver-javascript-developers/calendar/13867715/?a=cr1p_grp&amp;amp;amp;rv=cr1p&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Splittinng arguments&lt;/h2&gt;

&lt;p&gt;Math.min() accepts a set of values. When you would like to find the minimum value of an array, you can use the following trick:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Math.min.apply(Math, the_array);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;Function#apply&lt;/code&gt; receives an object for &amp;amp;quot;text&amp;amp;quot; and arguments in array.&lt;/p&gt;

&lt;p&gt;On the other hand Ruby has a feature of this issue as a syntactic sugar.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Math.min(*the_array)
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Abbreviating &amp;amp;quot;new&amp;amp;quot;&lt;/h2&gt;

&lt;p&gt;JavaScript uses &amp;amp;quot;new&amp;amp;quot; operator to create an instance.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var a = new A(x);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You may want to abbreviate the keyword &amp;amp;quot;new&amp;amp;quot; like&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var a = A(x);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can provide such class with the following trick.&lt;/p&gt;

&lt;script src='http://gist.github.com/471140.js?file=gistfile1.txt'/&gt;

&lt;p&gt;On the other hand, Ruby has separate namespace, so you can re-write the following code&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;a = A.new(x)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;as&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def A(x); A.new(x); end
a = A(x)
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;cloning an array&lt;/h2&gt;

&lt;p&gt;JS:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;array2 = array.slice(0);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ruby:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;array2 = array.dup
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The JS version is actually not just cloning but converts arguments object to array, so you can regard &lt;code&gt;Array#slice&lt;/code&gt; in JS as the combination of &lt;code&gt;dup&lt;/code&gt; and &lt;code&gt;to_a&lt;/code&gt; in Ruby.&lt;/p&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-8580416276416279735?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/8580416276416279735/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/07/javascript-tricks-in-ruby.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/8580416276416279735'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/8580416276416279735'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/07/javascript-tricks-in-ruby.html' title='JavaScript tricks in Ruby'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-8013028894743040702</id><published>2010-07-04T00:43:00.001-07:00</published><updated>2010-07-04T00:43:35.386-07:00</updated><title type='text'>Simple Mathematical Expression Converter with Jay</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;I wrote a simple mathematical expression converter with Jay: Yacc for Java for my study.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://www.cs.rit.edu/~ats/lp-2002-2/html/skript-23.html'&gt;http://www.cs.rit.edu/~ats/lp-2002-2/html/skript-23.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The sample code in this page is a mathematical expression interpreter. You can calculate four arithmetic operations and more like &lt;code&gt;1 + 2 * 3&lt;/code&gt; to &lt;code&gt;7&lt;/code&gt;. My code which will be described in this post converts expressions into reverse Polish notation ones like &lt;code&gt;1 + 2 * 3&lt;/code&gt; to &lt;code&gt;1 2 + 3 *&lt;/code&gt;.&lt;/p&gt;

&lt;script src='http://gist.github.com/463252.js?file=gistfile1.txt'/&gt;

&lt;p&gt;You can test this with the following commands if you already have Jay.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ /path-to-jay/jay -v -t ./Expr.jay &amp;amp;lt; /path-to-jay/java/skeleton.java &amp;amp;gt; Expr.java
$ javac -classpath /path-to-jay/yydebug/yydebug.jar:. Expr.java
$ echo '(1+2)*3 / (10 % 3) - (1 + 2 - 1 * 2.1)
(((10/3)))' | java -classpath /path-to-jay/yydebug/yydebug.jar:. Expr 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And you can ascertain the results are correct.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;1 2 + 3 * 10 3 % / 1 2 + 1 2.1 * - -
10 3 /
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Acknowledge and References&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Jay home page &lt;a href='http://www.informatik.uni-osnabrueck.de/alumni/bernd/jay/'&gt;http://www.informatik.uni-osnabrueck.de/alumni/bernd/jay/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;a lecture note &lt;a href='http://www.cs.rit.edu/~ats/lp-2002-2/html/skript-23.html'&gt;http://www.cs.rit.edu/~ats/lp-2002-2/html/skript-23.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I succeeded in achieving this with a great help by Masahiro Kimoto. Thanks!&lt;/p&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-8013028894743040702?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/8013028894743040702/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/07/simple-mathematical-expression.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/8013028894743040702'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/8013028894743040702'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/07/simple-mathematical-expression.html' title='Simple Mathematical Expression Converter with Jay'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-3479330200785439648</id><published>2010-06-29T00:15:00.001-07:00</published><updated>2010-09-20T11:29:07.389-07:00</updated><title type='text'>Introduction to JRuby - Bidirectional Communication</title><content type='html'>&lt;p&gt;Ruby program on JRuby can talk to Java and Java program with JRuby
libraries can talk to Ruby.&lt;/p&gt;

&lt;p&gt;There are many tutorials how to talk to Java on JRuby. It is
certainly useful for most programmers in the way that you can use
plenty of resources in Java platform. It is also important that you
don't have to know Java very much when you use JRuby.&lt;/p&gt;

&lt;p&gt;On the other hand there are less tutorials how to talk to Ruby from
Java side. This post will explain both sides that communication
from Ruby to Java and from Java to Ruby.&lt;/p&gt;

&lt;h2&gt;Ruby talks to Java&lt;/h2&gt;

&lt;p&gt;Assume you already have &lt;code&gt;Hi.java&lt;/code&gt; below.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Hi {
  public Hi() {
  }

  void f() {
    System.out.println("hi");
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Compile the code and generate JAR file.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ javac Hi.java
$ jar cf hi.jar Hi.class
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Next it's turn to write Ruby code. Write the following code into
&lt;code&gt;hi.rb&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'hi.jar'
Java::Hi.new.f
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Run it.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ jruby -v hi.rb
hi
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Cool! You can run the code on JRuby without setting $PATH.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ /Users/ujihisa/git/jruby/bin/jruby hi.rb
hi
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You wrote &lt;code&gt;Java::Hi.new.f&lt;/code&gt; but do you want to abbreviate Java?
Write the following code instead.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'hi.jar'
include_class Java::Hi
Hi.new.f
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You also can pass some Ruby objects to Java and get Ruby objects
from Java with JRuby.&lt;/p&gt;

&lt;p&gt;Hi.java:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Hi {
  public Hi() {
  }

  int f(int n) {
    return n + 1;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;hi.rb:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'hi.jar'
include_class Java::Hi
p Hi.new.f(10)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;result:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;11
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;Fixnum&lt;/code&gt; in Ruby was automatically converted as &lt;code&gt;int&lt;/code&gt; in Java
bidirectionally.&lt;/p&gt;

&lt;p&gt;Anyway, now you can talk to Java; you can use Java classes from
Ruby.&lt;/p&gt;

&lt;h2&gt;Handling Ruby objects in Java world&lt;/h2&gt;

&lt;p&gt;Let me show how to return a Ruby object in Java without using a
ruby code.&lt;/p&gt;

&lt;p&gt;The following method just returns the argument.&lt;/p&gt;

&lt;p&gt;Hi.java:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Hi {
  public Hi() {
  }

  Object f(Object x) {
    return x;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;hi.rb:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'hi.jar'
include_class Java::Hi
obj = Object.new
p Hi.new.f(obj) #=&amp;gt; #&amp;lt;Object:0xf8acdc&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This certainly works, but the Java code lacks the type information;
The &lt;code&gt;Object&lt;/code&gt; is the class in Java which means &lt;code&gt;void&lt;/code&gt; in C roughly,
but you actually wanted to represent &lt;code&gt;Object&lt;/code&gt; in Ruby.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Object&lt;/code&gt; in Ruby is &lt;code&gt;IRubyObject&lt;/code&gt; in Java with jruby library. I
mean, you should use it instead of just &lt;code&gt;Object&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;import org.jruby.runtime.builtin.IRubyObject;
class Calc {
  public Calc() {}

  IRubyObject f(IRubyObject n) {
    return n;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that I wrote &lt;code&gt;import&lt;/code&gt; statement in the top of the code.&lt;/p&gt;

&lt;p&gt;To compile the code, you have to specify &lt;code&gt;jruby.jar&lt;/code&gt; file.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ javac -classpath /Users/ujihisa/git/jruby/lib/jruby.jar Hi.java
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then after you made new JAR file you can run the same Ruby code in
securer way.&lt;/p&gt;

&lt;p&gt;Hi.java&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.RubyObjectAdapter;
import org.jruby.javasupport.JavaEmbedUtils;
class Hi {
  public Hi() {
  }

  IRubyObject f(IRubyObject x) {
    RubyObjectAdapter adapter = JavaEmbedUtils.newObjectAdapter();
    return adapter.callMethod(x, "greeting");
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;hi.rb&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'hi.jar'
include_class Java::Hi
obj = Object.new
def obj.greeting
  "how are you?"
end
p Hi.new.f(obj) #=&amp;gt; "how are you?"
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Java talks to Ruby&lt;/h2&gt;

&lt;p&gt;I've told about examples which bootstrap was Ruby. Next let's try
to do the same thing from the opposite side. You make a Ruby class
first, and then you use the class from Java.&lt;/p&gt;

&lt;p&gt;Hi.java:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;import org.jruby.embed.ScriptingContainer;

class Hi {
  public static void main(String[] args) {
    ScriptingContainer c = new ScriptingContainer();
    c.runScriptlet("p 1");
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and run it by the following code:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ javac -classpath /Users/ujihisa/git/jruby/lib/jruby.jar Hi.java
$ java -classpath /Users/ujihisa/git/jruby/lib/jruby.jar:. Hi
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that you have to specify the classpath not only in &lt;code&gt;javac&lt;/code&gt;
command but also in &lt;code&gt;java&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;You can check the version of JRuby library by writing
&lt;code&gt;c.runScriptlet("p RUBY_DESCRIPTION");&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;A complex example&lt;/h2&gt;

&lt;p&gt;Ruby calls a Java class which method calls Ruby method.&lt;/p&gt;

&lt;p&gt;hi.rb&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'hi.jar'
include_class Java::Hi
Hi.new(2).plus('3').show
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Hi.java&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;import org.jruby.Ruby;
import org.jruby.RubyObjectAdapter;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.javasupport.JavaEmbedUtils;

class Hi {
  int x;
  int y;

  public Hi(int n) {
    this.x = n;
    this.y = 0;
  }

  Hi plus(IRubyObject s) {
    RubyObjectAdapter adapter = JavaEmbedUtils.newObjectAdapter();
    this.y = Integer.parseInt(adapter.callMethod(s, "succ").asJavaString());
    return this;
  }

  void show() {
    System.out.printf("%s * (%s + 1) = %s\n", this.x, this.y, this.x + this.y);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;result:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;2 * (4 + 1) = 6
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Postscript&lt;/h2&gt;

&lt;p&gt;I explained how to execute a Ruby functionality like sending a
message to an object and how to evaluate a Ruby code (parsing and
execution). You may notice that there lacks the information how to
parse a Ruby code without execution. Currently there is no way to
do on JRuby, so I'm working on solving the challenge in a slow
manner.&lt;/p&gt;

&lt;h2&gt;References&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Nokogiri's source code is informative. I mostly referred
&lt;code&gt;ext/java/nokogiri/XmlSaxParserContext.java&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://kenai.com/projects/jruby/pages/RedBridge"&gt;http://kenai.com/projects/jruby/pages/RedBridge&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-3479330200785439648?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/3479330200785439648/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/06/introduction-to-jruby-bidirectional.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/3479330200785439648'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/3479330200785439648'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/06/introduction-to-jruby-bidirectional.html' title='Introduction to JRuby - Bidirectional Communication'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-4796948854831610872</id><published>2010-06-05T21:26:00.001-07:00</published><updated>2010-06-05T21:26:49.248-07:00</updated><title type='text'>Incremental Operator in JRuby</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;patch:&lt;/p&gt;

&lt;script src='http://gist.github.com/427292.js?file=gistfile1.txt'/&gt;

&lt;p&gt;difficulties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build. You need &lt;code&gt;jay&lt;/code&gt; to generate &lt;code&gt;.java&lt;/code&gt; file from &lt;code&gt;.y&lt;/code&gt; file by &lt;code&gt;bin/generate_parser&lt;/code&gt;. Jay is available &lt;a href='http://svn.codehaus.org/jruby/trunk/jay/'&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Type. My previous patches&lt;a href='http://ujihisa.blogspot.com/2009/07/incremental-operator-in-ruby.html'&gt;1&lt;/a&gt;&lt;a href='http://ujihisa.blogspot.com/2010/06/incremental-operator-in-rubinius.html'&gt;2&lt;/a&gt; can't work on Java with a little bit of fixes; you have to cast types explicitly.&lt;/li&gt;
&lt;li&gt;Separated. JRuby's parse is not monosyllabic like MRI's &lt;code&gt;parse.y&lt;/code&gt; or Rubinius' &lt;code&gt;grammar.y&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-4796948854831610872?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/4796948854831610872/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/06/incremental-operator-in-jruby.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/4796948854831610872'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/4796948854831610872'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/06/incremental-operator-in-jruby.html' title='Incremental Operator in JRuby'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-351449178053530351</id><published>2010-06-05T13:58:00.001-07:00</published><updated>2010-06-05T13:58:20.376-07:00</updated><title type='text'>Incremental Operator in Rubinius</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;&lt;img alt='plusplus' src='http://gyazo.com/03b3d663cdf90e56e28f7f52264a98f9.png'/&gt;&lt;/p&gt;

&lt;p&gt;patch:&lt;/p&gt;

&lt;script src='http://gist.github.com/426991.js?file=gistfile1.txt'/&gt;

&lt;p&gt;Apply the patch and run &lt;code&gt;rake install&lt;/code&gt;. Now you can increment variables!&lt;/p&gt;

&lt;script src='http://gist.github.com/426992.js?file=gistfile1.txt'/&gt;

&lt;p&gt;I met some pitfalls in working on this small Rubinius hack.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The parser is &lt;code&gt;lib/ext/melbourne/grammar.y&lt;/code&gt;. The Racc file &lt;code&gt;lib/ruby_parser.y&lt;/code&gt; is just a dummy.&lt;/li&gt;
&lt;li&gt;To refer a Symbol, MRI uses &lt;code&gt;rb_internal&lt;/code&gt; while Rubinius uses &lt;code&gt;rb_parser_sym&lt;/code&gt; in the parser.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rake build&lt;/code&gt; doesn't build the parser again. You have to run &lt;code&gt;rake install&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;References&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://ujihisa.blogspot.com/2009/07/incremental-operator-in-ruby.html'&gt;Incremental Operator in Ruby&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-351449178053530351?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/351449178053530351/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/06/incremental-operator-in-rubinius.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/351449178053530351'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/351449178053530351'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/06/incremental-operator-in-rubinius.html' title='Incremental Operator in Rubinius'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-7702002209289026603</id><published>2010-05-27T16:45:00.001-07:00</published><updated>2010-05-27T16:45:03.753-07:00</updated><title type='text'>An Experimental Twitter Clone with Rails</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;Let's make an experimental Twitter clone web app by Ruby on Rails version 3.&lt;/p&gt;

&lt;p&gt;The minimum features of Twitter clone app are below:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A visitor can sign up and get an account to become a user&lt;/li&gt;
&lt;li&gt;A user can post tweets&lt;/li&gt;
&lt;li&gt;A visitor and a user can see another user's one single tweet or a sequence of tweets&lt;/li&gt;
&lt;li&gt;A visitor and a user can see public timeline&lt;/li&gt;
&lt;li&gt;A user can follow another user&lt;/li&gt;
&lt;li&gt;A user can see &amp;amp;quot;timeline&amp;amp;quot; of the followings' tweets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I cut the following features for ease:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A user can see &amp;amp;quot;mentions&amp;amp;quot;&lt;/li&gt;
&lt;li&gt;A user can leave (unfollow) others&lt;/li&gt;
&lt;li&gt;A user can send or receive direct messages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But I also would want to add the following internal feature which the real Twitter seems to be using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A timeline is not created just in time, but created when a user of the participants posted a tweet&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This feature reduces the load time of reading a timeline.&lt;/p&gt;

&lt;h2&gt;So what's the difference?&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;It doesn't use any special software but just use Rails3&lt;/li&gt;
&lt;li&gt;It doesn't use a relational DB for storing tweets&lt;/li&gt;
&lt;li&gt;It is fast and scales (hopefully)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;The Product &amp;amp;quot;twi1&amp;amp;quot;&lt;/h2&gt;

&lt;p&gt;I named it &amp;amp;quot;twi1&amp;amp;quot; without thinking anything. That's here. &lt;a href='http://twi1.heroku.net/'&gt;http://twi1.heroku.net/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note that currently it doesn't work because heroku doesn't support writing a file. I should look for another way if I use heroku.&lt;/p&gt;

&lt;p&gt;The below screenshots are on my local server.&lt;/p&gt;

&lt;p&gt;&lt;img alt='User&amp;apos;s timeline' src='http://gyazo.com/481d6caa9e0ce814d93acc76941eadc9.png'/&gt;&lt;/p&gt;

&lt;p&gt;&lt;img alt='Public timeline' src='http://gyazo.com/6b1ace898ac7dac063339f06785b488d.png'/&gt;&lt;/p&gt;

&lt;p&gt;The public/user timeline is stored as the below.&lt;/p&gt;

&lt;script src='http://gist.github.com/416532.js?file=gistfile1.txt'/&gt;

&lt;p&gt;When a user posted a tweet, the following code runs.&lt;/p&gt;

&lt;script src='http://gist.github.com/416533.js?file=gistfile1.txt'/&gt;

&lt;p&gt;That just removed the last line and add two lines.&lt;/p&gt;

&lt;p&gt;To show the static timeline json file, I used the following short javascript codes.&lt;/p&gt;

&lt;script src='http://gist.github.com/416534.js?file=gistfile1.txt'/&gt;

&lt;p&gt;and in the HTML view file,&lt;/p&gt;

&lt;script src='http://gist.github.com/416535.js?file=gistfile1.txt'/&gt;

&lt;h2&gt;Actually&lt;/h2&gt;

&lt;p&gt;The current &lt;code&gt;twi1&lt;/code&gt; doesn't have the &amp;amp;quot;follow&amp;amp;quot; feature.&lt;/p&gt;

&lt;h2&gt;References&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://stackoverflow.com/questions/2453104/mongomapper-rails3-edge-undefined-method-to-key-on-form-for'&gt;http://stackoverflow.com/questions/2453104/mongomapper-rails3-edge-undefined-method-to-key-on-form-for&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='http://stackoverflow.com/questions/2255176/getting-undefined-method-username-for-usersession-no-credentials-provided-w'&gt;http://stackoverflow.com/questions/2255176/getting-undefined-method-username-for-usersession-no-credentials-provided-w&lt;/a&gt; (to run authlogin on heroku)&lt;/li&gt;
&lt;li&gt;&lt;a href='http://www.ibm.com/developerworks/library/wa-aj-jsonp1/'&gt;http://www.ibm.com/developerworks/library/wa-aj-jsonp1/&lt;/a&gt; (for jsonp)&lt;/li&gt;
&lt;/ul&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-7702002209289026603?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/7702002209289026603/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/05/experimental-twitter-clone-with-rails.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/7702002209289026603'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/7702002209289026603'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/05/experimental-twitter-clone-with-rails.html' title='An Experimental Twitter Clone with Rails'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-234551337471201265</id><published>2010-05-18T23:49:00.001-07:00</published><updated>2010-05-18T23:49:33.781-07:00</updated><title type='text'>April and May</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;I had been less techy time these days. I'll pick up techy events and happenings in April and May here.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GC Book Workshop in Japan

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://github.com/ujihisa/nari.gc/blob/master/README.md'&gt;http://github.com/ujihisa/nari.gc/blob/master/README.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;img alt='gc' src='http://farm5.static.flickr.com/4017/4591607991_0a88d1d5e8.jpg'/&gt;&lt;/li&gt;
&lt;li&gt;I tried to build Rubinius and failed&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Released VimJobs

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://vimjobs.heroku.com/'&gt;http://vimjobs.heroku.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;on Rails 3&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Accepted as a RubySoc mentor!&lt;/li&gt;
&lt;li&gt;Accepted as a RubyKaigi2010 speaker!&lt;/li&gt;
&lt;li&gt;Seattle.rb on May 18

&lt;ul&gt;
&lt;li&gt;Worked on tenderlove's psych issues&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;GHC LLVMBackend... failed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I mostly worked on building GHC LLVMBackend. I don't really want to say... but I have to clarify that GHC is a terrible software in the way that it's impossible to build. I hope I could avoid this problem.&lt;/p&gt;

&lt;p&gt;I also was suffered from frequent sudden crash of Vim. It's really annoying these days. I hope I could avoid this problem.&lt;/p&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-234551337471201265?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/234551337471201265/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/05/april-and-may.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/234551337471201265'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/234551337471201265'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/05/april-and-may.html' title='April and May'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm5.static.flickr.com/4017/4591607991_0a88d1d5e8_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-2751461140326645111</id><published>2010-04-27T07:53:00.001-07:00</published><updated>2010-04-27T07:53:34.265-07:00</updated><title type='text'>Several Ways of Defining Class/Instance Methods</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;This entry is for Ruby beginners.&lt;/p&gt;

&lt;h2&gt;Class Methods&lt;/h2&gt;

&lt;p&gt;Assume you have class &lt;code&gt;A&lt;/code&gt; and want to define a class method &lt;code&gt;c&lt;/code&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;class + def + self.&lt;/p&gt;

&lt;script src='http://gist.github.com/380812.js?file=gistfile1.txt'/&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;singleton class&lt;/p&gt;

&lt;script src='http://gist.github.com/380813.js?file=gistfile1.txt'/&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;class_eval + def&lt;/p&gt;

&lt;script src='http://gist.github.com/380814.js?file=gistfile1.txt'/&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;Instance Methods&lt;/h2&gt;

&lt;p&gt;Assume you have class &lt;code&gt;A&lt;/code&gt; and want to define an instance method &lt;code&gt;i&lt;/code&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;class + def&lt;/p&gt;

&lt;script src='http://gist.github.com/380815.js?file=gistfile1.txt'/&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;instance_eval + def&lt;/p&gt;

&lt;script src='http://gist.github.com/380816.js?file=gistfile1.txt'/&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;class_eval + define_method&lt;/p&gt;

&lt;script src='http://gist.github.com/380817.js?file=gistfile1.txt'/&gt;&lt;/li&gt;
&lt;/ol&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-2751461140326645111?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/2751461140326645111/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/04/several-ways-of-defining-classinstance.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/2751461140326645111'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/2751461140326645111'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/04/several-ways-of-defining-classinstance.html' title='Several Ways of Defining Class/Instance Methods'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-1797487212279831538</id><published>2010-04-15T14:11:00.001-07:00</published><updated>2010-04-15T14:11:34.387-07:00</updated><title type='text'>Public Methods of Kernel on Ruby 1.9 and 1.8</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;The stable version of MRI 1.9.2 will be released soon. Let's compare the differences between the latest ruby and the legacy ruby.&lt;/p&gt;

&lt;p&gt;Here this is the diff of the public methods of Kernel class on ruby 1.9.2dev and 1.8.7. I just used such command: &lt;code&gt;ruby -ve 'puts Kernel.public_methods.sort'&lt;/code&gt;.&lt;/p&gt;

&lt;script src='http://gist.github.com/367664.js?file=gistfile1.txt'/&gt;

&lt;p&gt;The differences were more than I thought.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;!&lt;/code&gt; became a method from a build-in operator&lt;/li&gt;
&lt;li&gt;Some mathematical libraries are now build-in&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Kernel.chomp&lt;/code&gt; worked like Perl, targetting &lt;code&gt;$_&lt;/code&gt;, but now it was eliminated&lt;/li&gt;
&lt;li&gt;&lt;code&gt;class_variable_get/set&lt;/code&gt; is now available besides &lt;code&gt;instance_variable_get/set&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;define_singleton_method&lt;/code&gt;!&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spawn&lt;/code&gt;&lt;a href='http://ujihisa.blogspot.com/2010/03/all-about-spawn.html'&gt;!&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-1797487212279831538?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/1797487212279831538/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/04/public-methods-of-kernel-on-ruby-19-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/1797487212279831538'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/1797487212279831538'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/04/public-methods-of-kernel-on-ruby-19-and.html' title='Public Methods of Kernel on Ruby 1.9 and 1.8'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-851876399779746371</id><published>2010-03-28T16:19:00.001-07:00</published><updated>2010-03-28T16:20:09.953-07:00</updated><title type='text'>How to Get Each Characters</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;&lt;code&gt;STDIN.getc&lt;/code&gt; returns a buffered character from STDIN. How do I get a character from STDIN immediately without buffering?&lt;/p&gt;

&lt;p&gt;This code looks well, but it doesn't work as you expect. The input characters will be still buffered.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;STDIN.sync = true
p STDIN.getc
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Curses.getch&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;require 'curses'
p Curses.getch
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This works, but there is an undesired side-effect. &lt;code&gt;Curses.getch&lt;/code&gt; clears the screen.&lt;/p&gt;

&lt;h2&gt;stty raw&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;orig_stty = `stty -g`
system 'stty raw echo'
p STDIN.getc
system 'stty', orig_stty
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This works, but some platform don't support the command.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Getting a character immediately looks easy, but it actually isn't easy.&lt;/p&gt;
    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-851876399779746371?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/851876399779746371/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/03/how-to-get-each-characters_28.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/851876399779746371'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/851876399779746371'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/03/how-to-get-each-characters_28.html' title='How to Get Each Characters'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-5717488964564382940</id><published>2010-03-21T22:30:00.001-07:00</published><updated>2010-03-21T22:30:59.570-07:00</updated><title type='text'>Spawn On JRuby</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;As the previous posts of this blog, ruby 1.9's &lt;code&gt;Kernel.spawn&lt;/code&gt; is very useful. I ported it to ruby 1.8 partly. How about on JRuby?&lt;/p&gt;

&lt;p&gt;Currently there are two ways of using &lt;code&gt;spawn&lt;/code&gt; on JRuby, but both of them have problem.&lt;/p&gt;

&lt;h2&gt;fork + exec + spawn-for-legacy library&lt;/h2&gt;

&lt;p&gt;I made a wrapper library &lt;a href='http://github.com/ujihisa/spawn-for-legacy'&gt;spawn-for-legacy&lt;/a&gt; which provides ruby 1.9 style &lt;code&gt;spawn&lt;/code&gt;, using &lt;code&gt;fork&lt;/code&gt; and &lt;code&gt;exec&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If JRuby has &lt;code&gt;fork&lt;/code&gt; and &lt;code&gt;exec&lt;/code&gt;, you can use &lt;code&gt;spawn-for-legacy&lt;/code&gt;. Unfortunatelly when you use &lt;code&gt;fork&lt;/code&gt; on JRuby, you have to set a command line option to JRuby interpreter.&lt;/p&gt;

&lt;script src='http://gist.github.com/339820.js?file=gistfile1.txt'/&gt;

&lt;p&gt;It also outputs an warning.&lt;/p&gt;

&lt;p&gt;I like this philosophy. JRuby only offeres platform independent features as the default. If you want to use platform dependent features, you need to state it explicitly.&lt;/p&gt;

&lt;p&gt;Anyway, now you can use &lt;code&gt;spawn&lt;/code&gt; on the platform provides &lt;code&gt;fork&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/jruby -J-Djruby.fork.enabled=true
require 'rubygems'
require 'sfl'
pid = spawn 'ruby', 'a.rb', :out =&amp;gt; '/dev/null'
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;spoon library&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;spoon&lt;/code&gt; is a rubygems library written by Charles Nutter. This offers &lt;code&gt;spawn&lt;/code&gt; using ffi. This works all platforms which provide &lt;code&gt;posix_spawn&lt;/code&gt;. Usually the number of platforms which provide &lt;code&gt;posix_spawn&lt;/code&gt; is more than the number of platforms which provide &lt;code&gt;fork&lt;/code&gt;, so &lt;code&gt;spoon&lt;/code&gt; is more platform independent.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/jruby
require 'rubygems'
require 'spoon'
pid = spawn 'ruby', 'a.rb'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Unfortunatelly current &lt;code&gt;spoon&lt;/code&gt; doesn't seem to support all features ruby 1.9's &lt;code&gt;spawn&lt;/code&gt; has. For example, you cannot redirect the output.&lt;/p&gt;

&lt;h2&gt;Future&lt;/h2&gt;

&lt;p&gt;The goal is already clear. I think someone will write a wrapper library.&lt;/p&gt;

&lt;h2&gt;References&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://ujihisa.blogspot.com/2010/03/all-about-spawn.html'&gt;http://ujihisa.blogspot.com/2010/03/all-about-spawn.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='http://github.com/headius/spoon/blob/master/lib/spoon.rb'&gt;http://github.com/headius/spoon/blob/master/lib/spoon.rb&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='http://blog.headius.com/2009/05/fork-and-exec-on-jvm-jruby-to-rescue.html'&gt;http://blog.headius.com/2009/05/fork-and-exec-on-jvm-jruby-to-rescue.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-5717488964564382940?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/5717488964564382940/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/03/spawn-on-jruby.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/5717488964564382940'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/5717488964564382940'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/03/spawn-on-jruby.html' title='Spawn On JRuby'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-2931466263825884288</id><published>2010-03-15T13:23:00.001-07:00</published><updated>2010-03-15T13:23:01.105-07:00</updated><title type='text'>at_exit is not Reliable</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;script src='http://gist.github.com/333281.js?file=gistfile1.txt'/&gt;

&lt;p&gt;You would expect that the output of this Ruby script is "testament", but the forked process will die without saying anything.
If the process doesn't receive 'KILL', but receives 'HUP', then the process will say the testament.&lt;/p&gt;

&lt;p&gt;How can I ensure doing something in the process is dying? Signal 'KILL' is uncatchable, so &lt;code&gt;trap&lt;/code&gt; doesn't work as well.&lt;/p&gt;

&lt;p&gt;&lt;img alt='1' src='http://gyazo.com/72fe09e5805f703b748eef7389b55fee.png'/&gt;&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;&lt;img alt='2' src='http://gyazo.com/fa53fb6c4ce763a438537335713477e0.png'/&gt;&lt;/p&gt;

&lt;p&gt;The testament won't arrive the user.&lt;/p&gt;

&lt;h2&gt;Solution: Use Another Process&lt;/h2&gt;

&lt;script src='http://gist.github.com/333282.js?file=gistfile1.txt'/&gt;

&lt;p&gt;I replaced &lt;code&gt;at_exit&lt;/code&gt; block to a fork block with the parent process' pid. It works!&lt;/p&gt;

&lt;p&gt;&lt;img alt='3' src='http://gyazo.com/07eccb4b9bc514020609905461f67eab.png'/&gt;&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;&lt;img alt='4' src='http://gyazo.com/dedcc05904b46d4d6c62d5d4992a08c6.png'/&gt;&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;&lt;img alt='5' src='http://gyazo.com/fe6f30151e98b6ef551f4ff34c8d8c84.png'/&gt;&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;&lt;img alt='6' src='http://gyazo.com/82d384a40419aef3c20389be76d57bfe.png'/&gt;&lt;/p&gt;

&lt;h2&gt;Appendix: Compatible Version&lt;/h2&gt;

&lt;p&gt;Windows doesn't support fork. Here is the equivalent code with &lt;code&gt;spawn&lt;/code&gt;.&lt;/p&gt;

&lt;script src='http://gist.github.com/333283.js?file=gistfile1.txt'/&gt;

&lt;p&gt;(Don't you have &lt;code&gt;spawn&lt;/code&gt; on your UNIX platform? Use &lt;code&gt;spawn-for-legacy&lt;/code&gt; library.)&lt;/p&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-2931466263825884288?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/2931466263825884288/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/03/atexit-is-not-reliable.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/2931466263825884288'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/2931466263825884288'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/03/atexit-is-not-reliable.html' title='at_exit is not Reliable'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-2318927955685288819</id><published>2010-03-11T17:03:00.001-08:00</published><updated>2010-03-11T22:09:03.124-08:00</updated><title type='text'>Double Fork Problem: Kill All Processes</title><content type='html'>&lt;p&gt;Ruby forks a ruby process which also forks a process.&lt;/p&gt;

&lt;script src="http://gist.github.com/330077.js?file=gistfile1.txt"&gt;&lt;/script&gt;

&lt;p&gt;If you kill &lt;code&gt;pid0&lt;/code&gt;, will the internal fork be automatically killed?&lt;/p&gt;

&lt;script src="http://gist.github.com/330078.js?file=gistfile1.txt"&gt;&lt;/script&gt;

&lt;p&gt;Try the previous code. This doesn't show 'bah!' message. It seems to be true that internal fork will be automatically killed.
But it's wrong. This code doesn't show 'bah!' message just because the internal fork didn't started yet when &lt;code&gt;Process.kill&lt;/code&gt; was called.&lt;/p&gt;

&lt;p&gt;Try to wait until both blocks are certainly for forked.&lt;/p&gt;

&lt;script src="http://gist.github.com/330079.js?file=gistfile1.txt"&gt;&lt;/script&gt;

&lt;p&gt;This code shows 'bah!' message after the main routine finished!&lt;/p&gt;

&lt;p&gt;So, let's think about how to kill the internal process.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The value of &lt;code&gt;pid1&lt;/code&gt; is not available in the outer main routine&lt;/li&gt;
&lt;li&gt;An external command &lt;code&gt;ps&lt;/code&gt; is not available in Windows&lt;/li&gt;
&lt;li&gt;Usually the process ID &lt;code&gt;pid0&lt;/code&gt; and &lt;code&gt;pid1&lt;/code&gt; are sequential, but depending on it is dangerous&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is the solution of it:&lt;/p&gt;

&lt;script src="http://gist.github.com/330080.js?file=gistfile1.txt"&gt;&lt;/script&gt;

&lt;p&gt;I added a line of &lt;code&gt;at_exit&lt;/code&gt;. This is cumbersome a little bit, but safe and easy.&lt;/p&gt;

&lt;h2&gt;With Spawn&lt;/h2&gt;

&lt;p&gt;The previous discussion was actually for getting ready. Windows doesn't have fork. We can use &lt;code&gt;spawn&lt;/code&gt; instead of &lt;code&gt;fork&lt;/code&gt; in most cases.&lt;/p&gt;

&lt;script src="http://gist.github.com/330081.js?file=gistfile1.txt"&gt;&lt;/script&gt;

&lt;p&gt;This succeeded!&lt;/p&gt;

&lt;h2&gt;One More Thing&lt;/h2&gt;

&lt;p&gt;When you have to fork a ruby process with &lt;code&gt;spawn&lt;/code&gt;, for example in case to rewrite &lt;code&gt;fork&lt;/code&gt; to &lt;code&gt;spawn&lt;/code&gt;, how do you write?&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fork { p Dir.pwd }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;to&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;spawn 'ruby', '-e', 'p Dir.pwd'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;is not correct. The ruby that booted the code itself is not always 'ruby'. It can be ruby19, jruby, rbx or other rubies. In this case, your the following approach.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'rbconfig'
spawn RbConfig::CONFIG['ruby_install_name'] + RbConfig::CONFIG['EXEEXT'], '-e', 'p Dir.pwd'
&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-2318927955685288819?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/2318927955685288819/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/03/double-fork-problem-kill-all-processes.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/2318927955685288819'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/2318927955685288819'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/03/double-fork-problem-kill-all-processes.html' title='Double Fork Problem: Kill All Processes'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-8913829445499992611</id><published>2010-03-11T12:58:00.001-08:00</published><updated>2010-03-11T13:02:05.853-08:00</updated><title type='text'>Compatible Array#flatten</title><content type='html'>&lt;p&gt;&lt;code&gt;Array#flatten&lt;/code&gt; with depth argument is useful.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[[1], [2], [[3], 4]].flatten(1)
#=&amp;gt; [1, 2, [3], 4]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That's been available since ruby 1.8.7, but older ruby such as ruby 1.8.6 doesn't support it.&lt;/p&gt;

&lt;p&gt;Here is the pure-ruby implementation of &lt;code&gt;Array#flatten&lt;/code&gt;. Use it in case.&lt;/p&gt;

&lt;script src="http://gist.github.com/329644.js?file=gistfile1.txt"&gt;&lt;/script&gt;

&lt;p&gt;I used it for my library &lt;code&gt;spawn-for-legacy&lt;/code&gt; to support ruby 1.8.6.&lt;/p&gt;

&lt;p&gt;Rails programmers don't need this code. Rails now only supports ruby newer than 1.8.7.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-8913829445499992611?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/8913829445499992611/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/03/compatible-arrayflatten.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/8913829445499992611'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/8913829445499992611'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/03/compatible-arrayflatten.html' title='Compatible Array#flatten'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-7410475485636139942</id><published>2010-03-07T00:11:00.001-08:00</published><updated>2010-03-07T06:24:24.773-08:00</updated><title type='text'>How To Run An External Command Asynchronously</title><content type='html'>&lt;p&gt;This issue looks easy, but is actually complex.&lt;/p&gt;

&lt;p&gt;On shell, you may run a command asynchronously just by adding &lt;code&gt;&amp;amp;&lt;/code&gt; at the end of command.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ sleep 10 &amp;amp;
[1] 8048
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can obtain the process ID, so you can stop the command.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ kill 8048
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;How can we run an external command on Ruby?&lt;/p&gt;

&lt;h3&gt;system()&lt;/h3&gt;

&lt;p&gt;The easiest way to run an external command is &lt;code&gt;system()&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;system 'sleep 10 &amp;amp;'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The return value of &lt;code&gt;system()&lt;/code&gt; is the exit code. In this case, the &lt;code&gt;system()&lt;/code&gt; returns true immediately after that ran, but it doesn't return process ID. To obtain the process ID, you can use &lt;code&gt;$?&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;system 'sleep 10 &amp;amp;'
p $? #=&amp;gt; 8050
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But unfortunatelly the &lt;code&gt;$?&lt;/code&gt; is not the processs ID of &lt;code&gt;sleep&lt;/code&gt;, but &lt;code&gt;sh -c sleep 10&lt;/code&gt;. There is a cussion. You cannot obtain the process ID of &lt;code&gt;sleep&lt;/code&gt; directly.&lt;/p&gt;

&lt;p&gt;One more problem: the notation is available only in UNIX based platform.&lt;/p&gt;

&lt;h3&gt;system() without shell&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;system 'sleep 10'&lt;/code&gt; uses shell but &lt;code&gt;system 'sleep', '10'&lt;/code&gt; doesn't use shell. Separate the arguments. But &lt;code&gt;system 'sleep', '10', '&amp;amp;'&lt;/code&gt; is not available.&lt;/p&gt;

&lt;h3&gt;Thread&lt;/h3&gt;

&lt;p&gt;To emulate &lt;code&gt;'&amp;amp;'&lt;/code&gt; feature, how about using Ruby's asynchronous features? Thread is the easiest way of that.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;t = Thread.start do
  system 'sleep', '10'
end
t.kill
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Looks good, but it doesn't work. Thread certainly will stop, but the external command booted by the thread will still alive.&lt;/p&gt;

&lt;h3&gt;exec()&lt;/h3&gt;

&lt;p&gt;How about using another way of booting an external command? There is &lt;code&gt;exec()&lt;/code&gt;, which roughly means the combination of &lt;code&gt;system()&lt;/code&gt; and &lt;code&gt;exit()&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;exec 'ls'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;roughly means&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;system 'ls'
exit
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So you think that the following code will work well.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;t = Thread.start do
  exec 'sleep', '10'
end
t.kill
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Unfortunatelly it doesn't work. You cannot use &lt;code&gt;exec()&lt;/code&gt; in a child thread.&lt;/p&gt;

&lt;h3&gt;fork()&lt;/h3&gt;

&lt;p&gt;Look for another way of supporting asynchronous feature on Ruby. &lt;code&gt;fork()&lt;/code&gt;. &lt;code&gt;fork()&lt;/code&gt; copies the Ruby process itself.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;pid = fork do
  exec 'sleep', '10'
end
Process.kill pid
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It works! &lt;code&gt;fork()&lt;/code&gt; is awesome!&lt;/p&gt;

&lt;p&gt;But there is a bad news. &lt;code&gt;Thread&lt;/code&gt; works on all platforms, but &lt;code&gt;fork&lt;/code&gt; works on only some platforms. I'm sorry Windows users and NetBSD users.&lt;/p&gt;

&lt;h3&gt;spawn()&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://ujihisa.blogspot.com/2010/03/all-about-spawn.html"&gt;spawn = fork + exec&lt;/a&gt;. &lt;code&gt;spawn()&lt;/code&gt; works on all platforms! It's perfect! But... ruby 1.8 doesn't have &lt;code&gt;spawn()&lt;/code&gt;...&lt;/p&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Ruby 1.9 + UNIX: Use &lt;code&gt;fork&lt;/code&gt; and &lt;code&gt;exec&lt;/code&gt;, or use &lt;code&gt;spawn&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Ruby 1.8 + UNIX: Use &lt;code&gt;fork&lt;/code&gt; and &lt;code&gt;exec&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Ruby 1.9 + Windows: Use &lt;code&gt;spawn&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Ruby 1.8 + Windows: Use other OS, other Ruby, or consider using &lt;a href="http://rubyforge.org/projects/win32utils/"&gt;this library&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-7410475485636139942?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/7410475485636139942/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/03/how-to-run-external-command.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/7410475485636139942'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/7410475485636139942'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/03/how-to-run-external-command.html' title='How To Run An External Command Asynchronously'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-7071035840657598569</id><published>2010-03-06T13:17:00.001-08:00</published><updated>2010-03-06T13:17:40.144-08:00</updated><title type='text'>How To Avoid The Worst Case</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;I broke an expensive unopened wine bottle. The white wine was spilt all over my kitchen.&lt;/p&gt;

&lt;p&gt;Yesterday I bought a wine bottle and a box of beer at a liquor store which is located far from my home. I bought them because they were on sale. To save my money, I came home on my foot, saving $1.75. Today I ate lunch and drunk a sip of beer. After the lunch, I was trying to get a snack. There was the wine bottle in front of the snack. My elbow hit the bottle, and broke it. The delicious expensive wine has gone. $14 and the heavy work has gone.&lt;/p&gt;

&lt;p&gt;While I was wiping the floor with smelling the wine, I was thinking what was the cause and how should I do after that. This incident was happened without any other people except for me. I'm the true culprit. So, how can I avoid such tragedy in my future?&lt;/p&gt;

&lt;p&gt;The causes are the following two. The fact I was drunk a little bit and the location of wine was not safe a little bit. Both of them are not crucial. But the incident certainly happened.&lt;/p&gt;

&lt;p&gt;This issue can be summarized as that we should assume anything for people who are in bad condition. People often become bad because of drowsiness, alcohol, anger and depression. Assume the condition. Never put glass products on the edge, or the place people can touch easily.&lt;/p&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-7071035840657598569?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/7071035840657598569/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/03/how-to-avoid-worst-case.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/7071035840657598569'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/7071035840657598569'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/03/how-to-avoid-worst-case.html' title='How To Avoid The Worst Case'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-5473805258587326673</id><published>2010-03-05T15:38:00.001-08:00</published><updated>2010-03-05T17:47:32.714-08:00</updated><title type='text'>All About Spawn</title><content type='html'>&lt;p&gt;Spawn = Fork + Exec, but works also on platforms which don't support fork.&lt;/p&gt;

&lt;p&gt;The usage of spawn is often said to be cryptic. Here I'll describe common cases.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;system('ls')&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;pid = spawn(['ls', 'ls'])
Process.wait(pid)
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;system('ls .')&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;pid = spawn('ls', '.')
Process.wait(pid)
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;system('ls . &amp;amp;')&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;pid = spawn('ls', '.')
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;system('ls . &amp;gt; a.txt')&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;pid = spawn('ls', '.', :out =&amp;gt; 'a.txt')
Process.wait(pid)
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;system('ls . &amp;gt;&amp;gt; a.txt')&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;pid = spawn('ls', '.', :out =&amp;gt; ['a.txt', 'a'])
Process.wait(pid)
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;system('ls . &amp;gt;&amp;amp; a.txt')&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;pid = spawn('ls', '.', [:out, :err] =&amp;gt; ['a.txt', 'w'])
Process.wait(pid)
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;IO.popen('cat a.txt') {|io| p io.read&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;i, o = IO.pipe
spawn('cat a.txt', :out =&amp;gt; o)
o.close
p i.read
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;system('make all &amp;amp;')&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;spawn('make', 'all)
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Dir.chdir('a') { system 'make all &amp;amp;' }&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;spawn('make', 'all', :chdir =&amp;gt; 'a')
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Passing ENV:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Shell: &lt;code&gt;$ AAA=1 make all &amp;amp;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Ruby: &lt;code&gt;ENV['AAA'] = '1'; system('make all &amp;amp;')&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Ruby with Spawn: &lt;code&gt;spawn({'AAA' =&amp;gt; '1'}, 'make', 'all')&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Further information can be available in &lt;code&gt;process.c&lt;/code&gt; in ruby trunk. Here the documentation from the file:&lt;/p&gt;

&lt;script src="http://gist.github.com/323424.js?file=gistfile1.txt"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-5473805258587326673?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/5473805258587326673/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/03/all-about-spawn.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/5473805258587326673'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/5473805258587326673'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/03/all-about-spawn.html' title='All About Spawn'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-4796611141566052517</id><published>2010-02-25T21:41:00.001-08:00</published><updated>2010-02-25T21:41:01.261-08:00</updated><title type='text'>LLVM Workshop at Online.sg</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;I gave a lecture about LLVM.&lt;/p&gt;

&lt;p&gt;The slides are available here: &lt;a href='http://github.com/ujihisa/onsg9/blob/master/slides.md'&gt;http://github.com/ujihisa/onsg9/blob/master/slides.md&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I emphasized the following points.
The optimizer of LLVM is awesome. I explained it with giving an example code.&lt;/p&gt;

&lt;p&gt;First, I generated a very long helloworld code. To generate lavish code, I used a Brainf**k compiler. The helloworld written in Brainf**k doesn't have something like String literal, so it's natural that the code is longer than necessary, therefore the generated LLVM assembly language code would be lavish as well.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ bfc.rb --llvm helloworld.bf &amp;gt; helloworld.ll
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The line number of the automatically generated LLVM assembly language code was 2714. Here let me optimize the code.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ llvms helloworld.ll -o a.bc
$ opt -O3 a.bc -o a2.bc
$ opt -O3 a2.bc -o a3.bc
$ llvm-dis a3.bc -o &amp;gt; a.ll
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The optimized code, &lt;code&gt;a.ll&lt;/code&gt;, is semantically equivalent to the original &lt;code&gt;helloworld.ll&lt;/code&gt;, though the lines of code is only 25.&lt;/p&gt;

&lt;p&gt;All attendees were surprized about the result.&lt;/p&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-4796611141566052517?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/4796611141566052517/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/02/llvm-workshop-at-onlinesg.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/4796611141566052517'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/4796611141566052517'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/02/llvm-workshop-at-onlinesg.html' title='LLVM Workshop at Online.sg'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-3044525485727353966</id><published>2010-02-25T13:25:00.001-08:00</published><updated>2010-02-25T17:12:58.892-08:00</updated><title type='text'>Redirecting STDOUT</title><content type='html'>&lt;p&gt;In writing spec in Ruby, you would often meet a situation that you
have to reduce outputting messages to STDOUT.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def f
  p 123
end

describe 'f' do
  it 'outputs &amp;quot;123\n&amp;quot; to stdout' do
    ...
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;How do you write it? Usually I assign a stringio object to
&lt;code&gt;$stdout&lt;/code&gt;. I guess many people use this approach.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def f
  p 123
end

# spec
require 'stringio'
results = $stdout = StringIO.new
f()
results.close_write
results.rewind
$stdout = STDOUT
p results.read #=&amp;gt; &amp;quot;123\n&amp;quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I started having an idea that &lt;code&gt;IO#reopen&lt;/code&gt; may be a better solution
of it. The code previously given looks obviously dirty.&lt;/p&gt;

&lt;p&gt;Finally I figured out the new approach was also dirty.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def f
  p 123
end

require 'tempfile'
results = Tempfile.new('a').path
a = STDOUT.dup
STDOUT.reopen(results, 'w')
f()
STDOUT.reopen(a)
p File.read(results)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;STDOUT.reopen&lt;/code&gt; doesn't accept an IO object, but only accepts a
Filename.&lt;/p&gt;

&lt;h2&gt;capture_io of minitest&lt;/h2&gt;

&lt;p&gt;Eric Hodel and Ryan Davis mentioned about &lt;code&gt;capture_io&lt;/code&gt; in &lt;code&gt;minitest&lt;/code&gt;. It uses the former approache.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def capture_io
  require 'stringio'

  orig_stdout, orig_stderr         = $stdout, $stderr
  captured_stdout, captured_stderr = StringIO.new, StringIO.new
  $stdout, $stderr                 = captured_stdout, captured_stderr

  yield

  return captured_stdout.string, captured_stderr.string
ensure
  $stdout = orig_stdout
  $stderr = orig_stderr
end
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Reference&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://www.ruby-forum.com/topic/187367"&gt;http://www.ruby-forum.com/topic/187367&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Eric Hodel++&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-3044525485727353966?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/3044525485727353966/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/02/redirecting-stdout.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/3044525485727353966'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/3044525485727353966'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/02/redirecting-stdout.html' title='Redirecting STDOUT'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-6516020285853869671</id><published>2010-02-17T12:22:00.001-08:00</published><updated>2010-02-17T12:22:50.622-08:00</updated><title type='text'>Multi Process Programming With DRb</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;Usually Ruby's thread works well, but when you have to use thread-unsafe features like &lt;code&gt;Dir.chdir&lt;/code&gt;, you need to use &lt;code&gt;fork&lt;/code&gt;. How can you wait for the children processes certainly finish the given tasks? The answer is to use DRb.&lt;/p&gt;

&lt;p&gt;I'll show an example. Prepare the following two files and run them:&lt;/p&gt;

&lt;p&gt;server.rb&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'drb'
x = Array.new(10, false)
def x.work(i)
  cost = rand
  puts "work(#{i}) costs #{cost}sec."
  sleep cost
  self[i] = true
end

def x.finish?
  return false unless all?
  DRb.stop_service
  true
end
DRb.start_service 'druby://localhost:1234', x

puts DRb.uri
DRb.thread.join
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;client.rb&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'drb'
x = DRbObject.new nil, 'druby://localhost:1234'
10.times do |i|
  fork { x.work(i) }
end

def wait_until
  loop do
    yield and return
    sleep 0.1
  end
end

t = Time.now
wait_until { x.finish? }
puts "#{Time.now - t}sec."
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;run!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ruby server.rb &amp;amp;
$ ruby client.rb
...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The server has 10 small virtual tasks which can be finished within 1 second. The &lt;code&gt;x.work(i)&lt;/code&gt; is the definition. Because of that, ideally the whole process finish maximally in 1sec, but practically because of reasons such as the definition os &lt;code&gt;wait_until&lt;/code&gt;, the whole process will finish maximally about 1.1sec.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'drb'
n = 10

# Server
x = Array.new(n, false)
def x.work(i)
  cost = rand
  puts "work(#{i}) costs #{cost}sec."
  sleep cost
  self[i] = true
end

def x.finish?
  return false unless all?
  DRb.stop_service
  true
end

fork do
  DRb.start_service 'druby://localhost:1234', x
  puts DRb.uri
  DRb.thread.join
end

# Client
def wait_until
  loop do
    yield and return
    sleep 0.1
  end
end

x = DRbObject.new nil, 'druby://localhost:1234'
sleep 0.2 # FIXME

n.times do |i|
  fork { x.work(i) }
end

t = Time.now
wait_until { x.finish? }
puts "#{Time.now - t}sec."
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I think you noticed that there is a dirty code in it. Yes, &lt;code&gt;"sleep 0.2 # FIXME"&lt;/code&gt; is. I tried to find how to wait until the DRbObject certainly connected, but I couldn't find any good solution.&lt;/p&gt;

&lt;h2&gt;Without &lt;code&gt;wait_until&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;I wrote the process at exit in the method in the server &lt;code&gt;x.work&lt;/code&gt; in order not to use &lt;code&gt;wait_until&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'drb'
n = 10

# Server
x = Array.new(n, false)
def x.work(i, t)
  cost = rand
  puts "work(#{i}) costs #{cost}sec."
  sleep cost
  self[i] = true

  if finish?
    puts "Total: #{Time.now - t}sec."
  end
end

def x.finish?
  return false unless all?
  DRb.stop_service
  true
end

fork do
  DRb.start_service 'druby://localhost:1234', x
  puts DRb.uri
  DRb.thread.join
end

# Client
x = DRbObject.new nil, 'druby://localhost:1234'
sleep 0.2 # FIXME

t = Time.now
n.times do |i|
  fork do
    x.work(i, t)
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;At first I used block passing style, but later I found that it's impossible to pass block through druby.&lt;/p&gt;

&lt;h2&gt;Or&lt;/h2&gt;

&lt;p&gt;Use &lt;code&gt;Rinda&lt;/code&gt; which is a higher layer library using &lt;code&gt;DRb&lt;/code&gt;.&lt;/p&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-6516020285853869671?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/6516020285853869671/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/02/multi-process-programming-with-drb.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/6516020285853869671'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/6516020285853869671'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/02/multi-process-programming-with-drb.html' title='Multi Process Programming With DRb'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-1319930159372166109</id><published>2010-02-14T16:30:00.001-08:00</published><updated>2010-02-14T16:30:47.808-08:00</updated><title type='text'>How To Save Both Standard And Error Logs By Some Processes On A Same Log File</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;h2&gt;Problem&lt;/h2&gt;

&lt;p&gt;Assuming that you need to save both standard and error logs by two processes on a same file.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ command1
mesg...
error...
mesg...
....

$ command2
mesg...
mesg...
mesg...
error..
....
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;How to do that? The following code looks good, but it doesn't work as you want.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ (command1 &amp;gt;&amp;amp; log.txt) &amp;amp;
$ (command2 &amp;gt;&amp;amp; log.txt) &amp;amp;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can find only the logs of &lt;code&gt;command2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;How about trying this?&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ (command1 2&amp;gt;&amp;amp;1 &amp;gt;&amp;gt; log.txt) &amp;amp;
$ (command2 2&amp;gt;&amp;amp;1 &amp;gt;&amp;gt; log.txt) &amp;amp;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It is better, but it doesn't work as you want as well.
The result is not chronically ordered because of buffering.&lt;/p&gt;

&lt;h2&gt;Solution&lt;/h2&gt;

&lt;p&gt;Do the following code:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ (command1 2&amp;gt;&amp;amp;1 | cat &amp;gt;&amp;gt; log.txt) &amp;amp;
$ (command2 2&amp;gt;&amp;amp;1 | cat &amp;gt;&amp;gt; log.txt) &amp;amp;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It's tricky. The part of &lt;code&gt;| cat &amp;gt;&amp;gt;&lt;/code&gt; means not to buffer the outputs.&lt;/p&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-1319930159372166109?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/1319930159372166109/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/02/how-to-save-both-standard-and-error.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/1319930159372166109'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/1319930159372166109'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/02/how-to-save-both-standard-and-error.html' title='How To Save Both Standard And Error Logs By Some Processes On A Same Log File'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-6584265317487699955</id><published>2010-02-11T18:23:00.001-08:00</published><updated>2010-02-11T18:23:46.400-08:00</updated><title type='text'>What I Made</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;&lt;object name='utv_n_850034' id='utv837889' height='386' width='480' classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000'&gt;&lt;param value='loc=%2F&amp;amp;autoplay=false&amp;amp;vid=4654935' name='flashvars'/&gt;&lt;param value='true' name='allowfullscreen'/&gt;&lt;param value='always' name='allowscriptaccess'/&gt;&lt;param value='http://www.ustream.tv/flash/video/4654935' name='src'/&gt;&lt;embed type='application/x-shockwave-flash' src='http://www.ustream.tv/flash/video/4654935' name='utv_n_850034' id='utv837889' allowscriptaccess='always' allowfullscreen='true' height='386' width='480' flashvars='loc=%2F&amp;amp;autoplay=false&amp;amp;vid=4654935'/&gt;&lt;/object&gt;&lt;/p&gt;

&lt;p&gt;I need more effort to distribute it.&lt;/p&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-6584265317487699955?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/6584265317487699955/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/02/what-i-made.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/6584265317487699955'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/6584265317487699955'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/02/what-i-made.html' title='What I Made'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-2024539140207840995</id><published>2010-02-07T10:38:00.001-08:00</published><updated>2010-02-07T10:38:50.315-08:00</updated><title type='text'>Introduction to Text Editors</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;If there were such a class titled "Introduction to Text Editors", I would be delighted to attend it.&lt;/p&gt;

&lt;p&gt;Here is just my imagination.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is Text

&lt;ul&gt;
&lt;li&gt;Text in Natural Languages&lt;/li&gt;
&lt;li&gt;Text in Programming Languages&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;What is Edit

&lt;ul&gt;
&lt;li&gt;Open, save and buffer&lt;/li&gt;
&lt;li&gt;Insert, delete and motion&lt;/li&gt;
&lt;li&gt;Modes: view, insert and command&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Operation and motion

&lt;ul&gt;
&lt;li&gt;Operations: delete, correct, yank and user-defined operations&lt;/li&gt;
&lt;li&gt;Motions: word, line and paragraph&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;User interface

&lt;ul&gt;
&lt;li&gt;Font, size, color and location&lt;/li&gt;
&lt;li&gt;Multiple windows&lt;/li&gt;
&lt;li&gt;Keyboard and other input devices&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Programming aids

&lt;ul&gt;
&lt;li&gt;Syntax highlighting&lt;/li&gt;
&lt;li&gt;Indentation&lt;/li&gt;
&lt;li&gt;Execute the code&lt;/li&gt;
&lt;li&gt;Hints&lt;/li&gt;
&lt;li&gt;Tagjump&lt;/li&gt;
&lt;li&gt;Handle related files&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Completion

&lt;ul&gt;
&lt;li&gt;Dictionary-based completion&lt;/li&gt;
&lt;li&gt;Buffer-based completion&lt;/li&gt;
&lt;li&gt;Omni completion&lt;/li&gt;
&lt;li&gt;Mixed completion&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Customization

&lt;ul&gt;
&lt;li&gt;Any behavior is customizable&lt;/li&gt;
&lt;li&gt;Key mapping&lt;/li&gt;
&lt;li&gt;Plugin&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The two major text editors, Vim and Emacs, have their own terms. I'd like to abstract them and give appropriate names.&lt;/p&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-2024539140207840995?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/2024539140207840995/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/02/introduction-to-text-editors.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/2024539140207840995'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/2024539140207840995'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/02/introduction-to-text-editors.html' title='Introduction to Text Editors'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-7689529580549970032</id><published>2010-02-05T21:56:00.001-08:00</published><updated>2010-02-05T21:56:50.746-08:00</updated><title type='text'>How To Check If You Have The Command</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;For example, to assume you have the command &lt;code&gt;svn&lt;/code&gt; and you don't have the command &lt;code&gt;svn1&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;which svn &amp;gt;&amp;amp;/dev/null
if [ $? == 0 ]; then
  echo You have svn
fi

which svn1 &amp;gt;&amp;amp;/dev/null
if [ $? == 1 ]; then
  echo You don\'t have svn1
fi
&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-7689529580549970032?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/7689529580549970032/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/02/how-to-check-if-you-have-command.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/7689529580549970032'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/7689529580549970032'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/02/how-to-check-if-you-have-command.html' title='How To Check If You Have The Command'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-1721480592334358061</id><published>2010-02-03T11:19:00.001-08:00</published><updated>2010-02-03T11:19:29.242-08:00</updated><title type='text'>The Right Way of Running External Commands on Vim</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;Today I was struggled with one of the worst behavior of Vim script.&lt;/p&gt;

&lt;p&gt;Try the following code on your Vim.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:!echo "#!"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Assuming you know that the command &lt;code&gt;:!&lt;/code&gt; is to run the given command on your shell. This looks equivalent to&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ echo "#!"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;on your terminal.&lt;/p&gt;

&lt;p&gt;But Vim will show a cryptic error. That's because both &lt;code&gt;#&lt;/code&gt; and &lt;code&gt;!&lt;/code&gt; are special letters for &lt;code&gt;:!&lt;/code&gt; command.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;!&lt;/code&gt; is the command previously ran. This is for the pseudo command &lt;code&gt;:!!&lt;/code&gt; which means that running the same command again.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#&lt;/code&gt; is the filename previously you edited.&lt;/li&gt;
&lt;li&gt;Similar in &lt;code&gt;%&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They may be useful for using Vim, but they make Vim script programmers crazy.&lt;/p&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-1721480592334358061?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/1721480592334358061/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/02/right-way-of-running-external-commands.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/1721480592334358061'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/1721480592334358061'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/02/right-way-of-running-external-commands.html' title='The Right Way of Running External Commands on Vim'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-5829115554928310711</id><published>2010-01-06T19:14:00.001-08:00</published><updated>2010-01-06T21:51:40.291-08:00</updated><title type='text'>Gmail In Other Fonts</title><content type='html'>&lt;p&gt;I use gmail. Gmail supports changing the layout. Gmail doesn't support changing the font family of messages. The default font family is Arial, but today I preferred to use Georgia instead. I tried to fix the font family with JavaScript, but it was totally tough.&lt;/p&gt;

&lt;p&gt;My first code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;javascript: var a = document.getElementsByTagName('iframe'); for (var i in a) { var b = a[i].contentWindow.document.getElementsByTagName('div'); for (var j in b) { b[j].setAttribute &amp;amp;&amp;amp; b[j].setAttribute('style', 'font-family: Georgia'); } }&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It changes all texts in all &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;s, but the layout will be completely broken. The content of an email appears on the bottom of the browswer.&lt;/p&gt;

&lt;p&gt;My second code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;javascript: var a = document.getElementsByTagName('iframe'); for (var i in a) { var b = a[i].contentWindow.document.getElementsByClassName('ii gt'); b.item() &amp;amp;&amp;amp; b.item().setAttribute('style', 'font-family: Georgia'); }&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It certainly changes the font of the content of an email, but when you moved to other messages, the font will back to the default ones.&lt;/p&gt;

&lt;p&gt;Finally, my friend &lt;a href="http://d.hatena.ne.jp/Hamachiya2/"&gt;Hamachiya2&lt;/a&gt; succeeded in writing the code of it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;javascript:(function(){ function cssr(doc, sel, dec) { var sheets=doc.styleSheets; if (sheets.length) { var tSheet=sheets[sheets.length-1]; tSheet.insertRule(sel+&amp;quot;{&amp;quot;+dec+&amp;quot;}&amp;quot;,tSheet.cssRules.length); } }; var ifr=document.getElementById('canvas_frame'); cssr(ifr.contentWindow.document, '.gs', 'font-family: Georgia'); })()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;p&gt;Bookmarklet is here: &lt;a href='javascript:(function(){ function cssr(doc, sel, dec) { var sheets=doc.styleSheets; if (sheets.length) { var tSheet=sheets[sheets.length-1]; tSheet.insertRule(sel+"{"+dec+"}",tSheet.cssRules.length); } }; var ifr=document.getElementById("canvas_frame"); cssr(ifr.contentWindow.document, ".gs", "font-family: Georgia"); })()'&gt;ujihisa&lt;/a&gt;. Drag it to your bookmark bar.&lt;/p&gt;

&lt;p&gt;To extend it for ease,&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(function(){
  function cssr(doc, sel, dec) {
    var sheets=doc.styleSheets;
    if (sheets.length) {
      var tSheet=sheets[sheets.length-1];
      tSheet.insertRule(sel+&amp;quot;{&amp;quot;+dec+&amp;quot;}&amp;quot;,tSheet.cssRules.length);
    }
  };
  var ifr=document.getElementById('canvas_frame');
  cssr(ifr.contentWindow.document, '.gs', 'font-family: Georgia');
})()
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This works perfectly. Use it and bless Hamachiya2!&lt;/p&gt;

&lt;p&gt;&lt;img src="http://gyazo.com/66f6b47aca6a6bba4091eec9e165ed24.png" alt="before" /&gt;&lt;/p&gt;

&lt;p&gt;before&lt;/p&gt;

&lt;p&gt;&lt;img src="http://gyazo.com/01e8c4d942f10b0cde400e1d391224b5.png" alt="after" /&gt;&lt;/p&gt;

&lt;p&gt;after&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-5829115554928310711?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/5829115554928310711/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/01/gmail-in-other-fonts.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/5829115554928310711'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/5829115554928310711'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/01/gmail-in-other-fonts.html' title='Gmail In Other Fonts'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-5464270134394408280</id><published>2010-01-03T14:12:00.001-08:00</published><updated>2010-01-03T14:12:30.489-08:00</updated><title type='text'>Knead Programming Language</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;&lt;img alt='a' src='http://gyazo.com/22fd1e07d1dae002ce056a0b52492175.png'/&gt;&lt;/p&gt;

&lt;p&gt;interesting&lt;/p&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-5464270134394408280?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/5464270134394408280/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/01/knead-programming-language.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/5464270134394408280'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/5464270134394408280'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/01/knead-programming-language.html' title='Knead Programming Language'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-7669762510868569702</id><published>2010-01-01T16:13:00.001-08:00</published><updated>2010-01-01T16:13:58.841-08:00</updated><title type='text'>Rabbit On Mac OS X</title><content type='html'>&lt;p&gt;To use &lt;code&gt;rabbit&lt;/code&gt; the presentation software written in Ruby, it is necessary to install gtk2.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ sudo port install gtk2
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;will never be finished. I gave up the installation and typed &lt;code&gt;&amp;lt;C-c&amp;gt;&lt;/code&gt;...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-7669762510868569702?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/7669762510868569702/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2010/01/rabbit-on-mac-os-x.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/7669762510868569702'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/7669762510868569702'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2010/01/rabbit-on-mac-os-x.html' title='Rabbit On Mac OS X'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-778672005817692267</id><published>2009-12-30T13:30:00.001-08:00</published><updated>2009-12-30T19:15:57.268-08:00</updated><title type='text'>Trying Out Bundler In 1 Minute</title><content type='html'>&lt;p&gt;Let's write an application which uses the gem library &lt;code&gt;&amp;quot;g&amp;quot;&lt;/code&gt; without installing it globally.&lt;/p&gt;

&lt;h2&gt;Mise En Place&lt;/h2&gt;

&lt;p&gt;Install &lt;code&gt;bundler&lt;/code&gt; to make the application easily.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gem install bundler
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And if you already have &lt;code&gt;g&lt;/code&gt;, uninstall it to make sure the application you'll make doesn't use the globally installed &lt;code&gt;g&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gem uninstall g
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Getting Started&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;$ mkdir ggg; cd ggg
$ vim Gemfile
gem 'g'
gem 'ruby-growl'

$ gem bundle
$ vim app.rb
require 'vendor/gems/environment'
require 'g'
g 'success!!!'

$ ruby app.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That's all!&lt;/p&gt;

&lt;p&gt;For your information:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ tree
.
|-- Gemfile
|-- app.rb
|-- bin
|   `-- growl
`-- vendor
    `-- gems
        |-- cache
        |   |-- g-1.3.0.gem
        |   `-- ruby-growl-1.0.1.gem
        |-- doc
        |-- environment.rb
        |-- gems
        |   |-- g-1.3.0
        |   |   |-- README.markdown
        |   |   |-- Rakefile
        |   |   |-- VERSION
        |   |   |-- g.gemspec
        |   |   |-- lib
        |   |   |   `-- g.rb
        |   |   `-- spec
        |   |       `-- g_spec.rb
        |   `-- ruby-growl-1.0.1
        |       |-- LICENSE
        |       |-- Manifest.txt
        |       |-- Rakefile
        |       |-- bin
        |       |   `-- growl
        |       |-- lib
        |       |   `-- ruby-growl.rb
        |       `-- test
        |           `-- test_ruby-growl.rb
        `-- specifications
            |-- g-1.3.0.gemspec
            `-- ruby-growl-1.0.1.gemspec

14 directories, 20 files
&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-778672005817692267?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/778672005817692267/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2009/12/trying-out-bundler-in-1-minute.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/778672005817692267'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/778672005817692267'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2009/12/trying-out-bundler-in-1-minute.html' title='Trying Out Bundler In 1 Minute'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-902445256506336381</id><published>2009-12-28T13:15:00.001-08:00</published><updated>2009-12-28T13:15:21.341-08:00</updated><title type='text'>Usually Something, But If...</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;Which do you prefer to write in Ruby?&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;if boundary_condition
  code_for_the_extreme_case
else
  code_for_the_typical_case
  ...
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Or&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;unless boundary_condition # `if !boundary_condition` as well.
  code_for_the_typical_case
  ...
else
  code_for_the_extreme_case
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In such cases, first I try to use guards. This is straightforward.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;return code_for_the_extreme_case if boundary_condition
code_for_the_typical_case
...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But sometimes I cannot use such notation in cases where not to use &lt;code&gt;return&lt;/code&gt; or &lt;code&gt;break&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;Solution&lt;/h2&gt;

&lt;p&gt;I made a DSL for this problem.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class UsuallyPending
  instance_methods.map {|i| i.to_s }.
    reject {|i| /__/ =~ i }.
    each {|m| undef_method m }

  def initialize(b1)
    @b1 = b1
  end

  def but_if(cond, &amp;amp;b2)
    if cond
      b2.call
    else
      @b1.call
    end
  end
end

def usually(&amp;amp;b1)
  UsuallyPending.new(b1)
end

usually do
  p ARGV
  p 'hello!'
end.but_if ARGV.empty? do
  p 'Give me arguments!'
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is a straightforward expansion of &lt;em&gt;postpositive if&lt;/em&gt; with block instead of a value.&lt;/p&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-902445256506336381?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/902445256506336381/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2009/12/usually-something-but-if.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/902445256506336381'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/902445256506336381'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2009/12/usually-something-but-if.html' title='Usually Something, But If...'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-9176743361155502449</id><published>2009-12-27T14:24:00.001-08:00</published><updated>2009-12-30T21:18:34.491-08:00</updated><title type='text'>BFC: Brainf\*\*k Compilers</title><content type='html'>&lt;p&gt;Today I released
&lt;a href="http://github.com/ujihisa/bfc/tree/v1.0"&gt;BFC 1.0&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;BFC: Brainf**k Compilers
&lt;a href="http://github.com/ujihisa/bfc"&gt;http://github.com/ujihisa/bfc&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;bfc.rb&lt;/code&gt; is a compiler written in Ruby, which can compile BF code
to Ruby, C, Haskell, Scheme and LLVM.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://gyazo.com/edee5a67efaf377c0b442ad13d441407.png" alt="BFC Shot" /&gt;&lt;/p&gt;

&lt;h2&gt;USAGE OF BFC&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;$ ./bfc.rb --help
$ ./bfc.rb [-v|--version]

$ ./bfc.rb [-r|--ruby]    helloworld.bf &amp;gt; helloworld.rb
$ ./bfc.rb [-c|--c]       helloworld.bf &amp;gt; helloworld.c
$ ./bfc.rb [-h|--haskell] helloworld.bf &amp;gt; helloworld.hs
$ ./bfc.rb [-l|--llvm]    helloworld.bf &amp;gt; helloworld.ll
$ ./bfc.rb [-s|--scheme]  helloworld.bf &amp;gt; helloworld.scm

$ cat helloworld.bf | ./bfc.rb --ruby
$ ./bfc.rb [-r|--ruby|-c|--c|-h|--haskell|-l|--llvm] helloworld.bf --run
$ ./bfc.rb [-c|--c] helloworld.bf --without-while &amp;gt; helloworld.c
$ spec ./bfc.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;THE BRAINF**K LANGUAGE&lt;/h2&gt;

&lt;p&gt;According to Wikipedia, the programming language Brainf**k has
the following 8 tokens that each have semantics. Here is the
equivalent transformation from Brainf**k to C.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://gyazo.com/9bfabec06e94a32d2ad3bee624296efc.png" alt="table" /&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;bfc.rb&lt;/code&gt; converts BF codes to each languages mostly based on
the table.&lt;/p&gt;

&lt;p&gt;C Translation Table in &lt;code&gt;bfc.rb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;',' =&amp;gt; '*h=getchar();',
'.' =&amp;gt; 'putchar(*h);',
'-' =&amp;gt; '--*h;',
'+' =&amp;gt; '++*h;',
'&amp;lt;' =&amp;gt; '--h;',
'&amp;gt;' =&amp;gt; '++h;',
'[' =&amp;gt; 'while(*h){',
']' =&amp;gt; '}'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ruby Translation Table in &lt;code&gt;bfc.rb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;',' =&amp;gt; 'a[i]=STDIN.getc.ord',
'.' =&amp;gt; 'STDOUT.putc(a[i])',
'-' =&amp;gt; 'a[i]-=1',
'+' =&amp;gt; 'a[i]+=1',
'&amp;lt;' =&amp;gt; 'i-=1',
'&amp;gt;' =&amp;gt; 'i+=1',
'[' =&amp;gt; 'while a[i]!=0',
']' =&amp;gt; 'end'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;They are straightforward enough not to be explained the detail.&lt;/p&gt;

&lt;p&gt;In the same way, we can write translation tables for most
programming languages except special languages including Haskell
and Assembly languages.&lt;/p&gt;

&lt;h2&gt;TRANSLATING TO HASKELL&lt;/h2&gt;

&lt;p&gt;Translating BF to Haskell needs two tricks. Haskell was difficult
to handle BF because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Variables in Haskell are not allowed to be re-assigned

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;++h&lt;/code&gt; is impossible&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There's no feature like &lt;code&gt;while&lt;/code&gt; statement&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So I used IO Monad with biding same-name variables, and defined
&lt;code&gt;while&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;Haskell Translation Table in &lt;code&gt;bfc.rb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;',' =&amp;gt; 'tmp &amp;lt;- getChar; h &amp;lt;- return $ update (\_ -&amp;gt; ord tmp) i h;',
'.' =&amp;gt; 'putChar $ chr $ h !! i;',
'-' =&amp;gt; 'h &amp;lt;- return $ update (subtract 1) i h;',
'+' =&amp;gt; 'h &amp;lt;- return $ update (+ 1) i h;',
'&amp;lt;' =&amp;gt; 'i &amp;lt;- return $ i - 1;',
'&amp;gt;' =&amp;gt; 'i &amp;lt;- return $ i + 1;',
'[' =&amp;gt; '(h, i) &amp;lt;- while (\(h, i) -&amp;gt; (h !! i) /= 0) (\(h, i) -&amp;gt; do {',
']' =&amp;gt; 'return (h, i);}) (h, i);'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And the definition of &lt;code&gt;while&lt;/code&gt; is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;while cond action x
 cond x    = action x &amp;gt;&amp;gt;= while cond action
 otherwise = return x
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is short, but can handle loop with changing the value with
larger scope like C's.&lt;/p&gt;

&lt;h2&gt;TRANSLATING TO C WITHOUT WHILE STATEMENTS&lt;/h2&gt;

&lt;p&gt;Unlike the effort on Haskell, it is impossible to write simple
translation table for C when I can use only &lt;code&gt;goto&lt;/code&gt; for control
flows instead of &lt;code&gt;while&lt;/code&gt; statements. So I made the compile to have
label counters to make labels for &lt;code&gt;goto&lt;/code&gt; a lot.&lt;/p&gt;

&lt;p&gt;Excerpt from &lt;code&gt;bfc.c&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;when ','; '*h=getchar();'
when '.'; 'putchar(*h);'
when '-'; '--*h;'
when '+'; '++*h;'
when '&amp;lt;'; '--h;'
when '&amp;gt;'; '++h;'
when '['; &amp;quot;do#{counter += 1}:&amp;quot;
when ']'
  &amp;quot;if (*h != 0) goto do#{counter}; else goto end#{counter};&amp;quot; &amp;lt;&amp;lt;
  &amp;quot;end#{counter}:&amp;quot;
end
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;TRANSLATING TO LLVM&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://ujihisa.blogspot.com/2009/12/llvm-for-starters.html"&gt;LLVM Assembly language&lt;/a&gt;
is similar to Haskell to the extent of the prohibition of
re-assignments, and not similar to Haskell to the extend of having
&lt;code&gt;do&lt;/code&gt; syntax for Monad. So I decided to use pointers to store
values. Also, LLVM needs many temporary variables which cannot be
re-assigned, so I used counters again to use temporary constants.&lt;/p&gt;

&lt;p&gt;The translation table with counters is too big to paste here, so
I'll just show the definition of &lt;code&gt;'+'&lt;/code&gt; which means &lt;code&gt;'++h'&lt;/code&gt; in C.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;when '+'
  a = tc += 1; b = tc += 1; c = tc += 1; d = tc += 1
  &amp;quot;%tmp#{a} = load i32* %i, align 4\n&amp;quot; &amp;lt;&amp;lt;
  &amp;quot;%tmp#{b} = getelementptr [1024 x i8]* %h, i32 0, i32 %tmp#{a}\n&amp;quot; &amp;lt;&amp;lt;
  &amp;quot;%tmp#{c} = load i8* %tmp#{b}, align 1\n&amp;quot; &amp;lt;&amp;lt;
  &amp;quot;%tmp#{d} = add i8 1, %tmp#{c}\n&amp;quot; &amp;lt;&amp;lt;
  &amp;quot;store i8 %tmp#{d}, i8* %tmp#{b}, align 1\n&amp;quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(where &lt;code&gt;tc&lt;/code&gt; is the abbreviation of &lt;code&gt;tmp counter&lt;/code&gt;.)&lt;/p&gt;

&lt;p&gt;One more thing. LLVM is famous for its aggressive optimizations.
For example, the result of the conversion from &lt;code&gt;helloworld.bf&lt;/code&gt; to
LLVM Assembly Language is very long.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ./bfc.rb --llvm ./helloworld.bf | wc -l
2842
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But once you optimize the assembly by &lt;code&gt;opt&lt;/code&gt; command of LLVM, the
line of code will become shorter and more succinct.&lt;/p&gt;

&lt;h2&gt;SUMMARY&lt;/h2&gt;

&lt;p&gt;BFC supports compiling BF to the following language.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ruby&lt;/li&gt;
&lt;li&gt;C&lt;/li&gt;
&lt;li&gt;Haskell&lt;/li&gt;
&lt;li&gt;LLVM Assembly Language&lt;/li&gt;
&lt;li&gt;Scheme&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In some languages it was easy to write the translator, but Haskell
and LLVM was tough for me.&lt;/p&gt;

&lt;p&gt;If I have a plenty of time, I'd like to try these challenges:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Compiling to Erlang&lt;/li&gt;
&lt;li&gt;Compiling to IA-32 Assembly Language&lt;/li&gt;
&lt;li&gt;Compiling to LLVM Bitcode&lt;/li&gt;
&lt;li&gt;More Spec!&lt;/li&gt;
&lt;li&gt;Benchmark Suite&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Anyway, I recommend you to take a look at the BFC. Enjoy!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-9176743361155502449?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/9176743361155502449/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2009/12/bfc-brainfk-compilers.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/9176743361155502449'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/9176743361155502449'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2009/12/bfc-brainfk-compilers.html' title='BFC: Brainf\*\*k Compilers'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-4748151299482435232</id><published>2009-12-26T12:09:00.001-08:00</published><updated>2009-12-26T12:13:52.645-08:00</updated><title type='text'>LLVM For Starters</title><content type='html'>&lt;h2&gt;Installation of LLVM Compiler and Runtime&lt;/h2&gt;

&lt;p&gt;See the previous post.&lt;/p&gt;

&lt;h2&gt;Overview of LLVM&lt;/h2&gt;

&lt;p&gt;To write a helloworld application, you can choose a path where to start. The typical path is,&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Write a code in &lt;em&gt;LLVM Assembly Language&lt;/em&gt; (.ll)

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;$ vim sample.ll&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Compile it to &lt;em&gt;LLVM Bytecode&lt;/em&gt; (.bc)

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;$ llvm-as sample.ll&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Run it on LLVM interpreter

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;$ lli sample.bc&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Or,&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;ditto&lt;/li&gt;
&lt;li&gt;ditto&lt;/li&gt;
&lt;li&gt;Compile it to Executable Binary File

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;$ llc sample.bc&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Run it!

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;$ ./sample&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this post, I'll explaing about the first step &amp;quot;LLVM Assembly Language&amp;quot;.&lt;/p&gt;

&lt;h2&gt;Helloworld in LLVM Assembly Language&lt;/h2&gt;

&lt;p&gt;LLVM is not a stack machine but a register machine.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://gyazo.com/0a79714c1bb3e73195c4a8ba418d1af3.png" alt="tableoftype" /&gt;&lt;/p&gt;

&lt;p&gt;(This table is from &lt;a href="http://en.wikipedia.org/wiki/Comparison_of_application_virtual_machines"&gt;wikipedia&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Let's write helloworld application. Before that, I'll show the equivalent code in C.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;int main() {
  puts(&amp;quot;Hello, world!&amp;quot;);
  return 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In LLVM Assembly Language, the code will be written as below.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@str = internal constant [14 x i8] c&amp;quot;Hello, world!\00&amp;quot;
declare i32 @puts(i8*)
define i32 @main()
{
  call i32 @puts( i8* getelementptr ([14 x i8]* @str, i32 0,i32 0))
  ret i32 0
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This code suggests the following notices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We can write an integer number directly in the assembly code, on the other hand, we cannot write a string directly.&lt;/li&gt;
&lt;li&gt;The long name &lt;code&gt;getelementptr&lt;/code&gt; seems to be &lt;code&gt;*&lt;/code&gt; in C.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If I write helloworld in C like the LLVM Assembly code, it is like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;char str[14] = &amp;quot;Hello, world!&amp;quot;;
int main() {
  puts((char *)str);
  return 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Fibonacci in in LLVM Assembly Language&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://blog.netswitch.jp/articles/2009/12/25/fibonacci-number-in-llvm"&gt;Nanki&lt;/a&gt; wrote Fibonacci in LLVM Assembly Language.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@str = internal constant [4 x i8] c&amp;quot;%d\0A\00&amp;quot;

define void @main() nounwind {
init:
  br label %loop
loop:
  %i = phi i32 [0, %init], [%i.next, %loop]
  %fib = call i32 @fib(i32 %i)

  call i32 @printf( i8* getelementptr ([4 x i8]* @str, i32 0,i32 0), i32 %fib)

  %i.next = add i32 %i, 1

  %cond = icmp ult i32 %i.next, 30
  br i1 %cond, label %loop, label %exit

exit:
  ret void
}

define i32 @fib(i32 %n) nounwind {
  %cond = icmp ult i32 %n, 2
  br i1 %cond, label %c1, label %c2

c1:
  ret i32 1
c2:
  %n1 = sub i32 %n, 1
  %n2 = sub i32 %n, 2

  %fib1 = call i32 @fib(i32 %n1)
  %fib2 = call i32 @fib(i32 %n2)

  %r = add i32 %fib1, %fib2
  ret i32 %r
}

declare i32 @printf(i8*, ...) nounwind
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To understand the code deeper, let me write back the code in C.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#include&amp;lt;stdio.h&amp;gt;
int fibonacci(int n);

int main() {
  int i, i_next, fib;
init:
  i = 0, i_next = 0;
loop:
  i = i_next;
  fib = fibonacci(i);
  printf(&amp;quot;%d\n&amp;quot;, fib);
  i_next = i + 1;
  if (i_next &amp;lt; 30) {
    goto loop;
  } else {
    goto exit;
  }
exit:
  return 0;
}

int fibonacci(int n) {
  int cond, n1, n2, fib1, fib2, r;
  cond = n &amp;lt; 2;
  if (cond) {
    goto c1;
  } else {
    goto c2;
  }
c1:
  return 1;
c2:
  n1 = n - 1;
  n2 = n - 2;
  fib1 = fibonacci(n1);
  fib2 = fibonacci(n2);
  r = fib1 + fib2;
  return r;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
&lt;li&gt;LLVM Assembly Language enables us to use the same name both for a variable and a function because of the existence of prefix&lt;/li&gt;
&lt;li&gt;LLVM Assembly Language cannot handle many calculation at the same time like &lt;code&gt;return fib(n-2) + fib(n-1)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-4748151299482435232?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/4748151299482435232/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2009/12/llvm-for-starters.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/4748151299482435232'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/4748151299482435232'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2009/12/llvm-for-starters.html' title='LLVM For Starters'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-4157006162328434162</id><published>2009-12-22T01:06:00.001-08:00</published><updated>2009-12-22T01:06:07.031-08:00</updated><title type='text'>Let's Try LLVM</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;Mac OS X has LLVM compiler, but doesn't have LLVM Assembler. Let's start installing the trunk LLVM on your Mac.&lt;/p&gt;

&lt;p&gt;According to &lt;a href='http://llvm.org/docs/GettingStarted.html#checkout'&gt;http://llvm.org/docs/GettingStarted.html#checkout&lt;/a&gt;,&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ cd ~/src
$ svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
$ cd llvm
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the directory there is &lt;code&gt;/docs&lt;/code&gt; directory which contains many html files. Check them.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ./configure --prefix=/Users/ujihisa/src/llvm/usr
$ gmake -k |&amp;amp; tee gnumake.out
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It took long time. After the build process, I found an interesting note.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;...
gmake[1]: Leaving directory `/Users/ujihisa/src/llvm/bindings'
llvm[0]: ***** Completed Debug Build
llvm[0]: ***** Note: Debug build can be 10 times slower than an
llvm[0]: ***** optimized build. Use make ENABLE_OPTIMIZED=1 to
llvm[0]: ***** make an optimized build. Alternatively you can
llvm[0]: ***** configure with --enable-optimized.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I should have set &lt;code&gt;--enable-optimized&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Anyway, let the installation finish.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ gmake install
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It also took time.&lt;/p&gt;

&lt;p&gt;Don't forget to make path to the &lt;code&gt;./usr/bin/&lt;/code&gt;. There are many llvm-related executable files.&lt;/p&gt;

&lt;h2&gt;Hello, world!&lt;/h2&gt;

&lt;p&gt;Let's write hello world on LLVM!&lt;/p&gt;

&lt;p&gt;I referred &lt;a href='http://projects.prabir.me/compiler/wiki/LLVMHelloWorldTutorial.ashx'&gt;this page&lt;/a&gt;. The sample code contains a small mistakes, so I fixed.&lt;/p&gt;

&lt;p&gt;Write the following code on &lt;code&gt;a.ll&lt;/code&gt; (not &lt;code&gt;a.11&lt;/code&gt;):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@str = internal constant [13 x i8] c"hello world\0A\00"

define void @main() nounwind
{
  %temp = call i32 @printf( i8* getelementptr ([13 x i8]* @str, i32 0,i32 0))
  ret void;
}

declare i32 @printf(i8*, ...) nounwind
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Assemble it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ llvm-as -f a.ll
$ lli a.bc
hello world
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Yay!&lt;/p&gt;

&lt;p&gt;The generated file &lt;code&gt;a.bc&lt;/code&gt; is a binary file.&lt;/p&gt;

&lt;h2&gt;Vim&lt;/h2&gt;

&lt;p&gt;Fortunately the svn repository contains a vim script for llvm named &lt;code&gt;llvm.vim&lt;/code&gt;. You should install it if you're a vimmer.&lt;/p&gt;

&lt;h2&gt;(To be continued...)&lt;/h2&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-4157006162328434162?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/4157006162328434162/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2009/12/let-try-llvm.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/4157006162328434162'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/4157006162328434162'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2009/12/let-try-llvm.html' title='Let&amp;#39;s Try LLVM'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-5772925658043230786</id><published>2009-12-21T15:34:00.001-08:00</published><updated>2009-12-21T15:34:49.703-08:00</updated><title type='text'>Today's RubySpec (Dec 21, 2009)</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;I succeeded in fixing RubySpec to pass all String specs both in Ruby 1.8.7 and Ruby 1.9.2. yay!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ /usr/bin/ruby ../mspec/bin/mspec ./core/string/*.rb -t ~/rubies/bin/ruby192
ruby 1.9.2dev (2009-12-21 trunk 26145) [i386-darwin9.8.0]
.............................................................................................

Finished in 0.559929 seconds

93 files, 1083 examples, 6132 expectations, 0 failures, 0 errors
$ /usr/bin/ruby ../mspec/bin/mspec ./core/string/*.rb -t ~/rubies/bin/ruby187
ruby 1.8.7 (2009-07-30 patchlevel 192) [i686-darwin9.7.0]
.............................................................................................

Finished in 0.483685 seconds

93 files, 889 examples, 5620 expectations, 0 failures, 0 errors
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;New knowledges for me&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;String#squeeze&lt;/code&gt;, &lt;code&gt;#count&lt;/code&gt; and &lt;code&gt;#delete&lt;/code&gt; receive string sequence like &lt;code&gt;"a-c"&lt;/code&gt;.
 In Ruby 1.8, an invalid sequence like &lt;code&gt;"c-a"&lt;/code&gt; is just regarded as empty sequence.
 On the other hand, in Ruby 1.9, it raises an &lt;code&gt;ArgumentError&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;"\u0085"&lt;/code&gt; is &lt;a href='http://www.fileformat.info/info/unicode/char/0085/index.htm'&gt;NEL: Next Line&lt;/a&gt; in utf-8.
 On my Terminal, it looks like &lt;code&gt;"\n"&lt;/code&gt;. But actually "n" and NEL are completely different characters.&lt;/li&gt;
&lt;li&gt;&lt;a href='http://ujihisa.blogspot.com/2009/12/string-differs-between-ruby-18-and-19.html'&gt;&lt;code&gt;String#%&lt;/code&gt; Differs Between Ruby 1.8 and 1.9&lt;/a&gt; (the previous blog post)&lt;/li&gt;
&lt;/ul&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-5772925658043230786?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/5772925658043230786/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2009/12/today-rubyspec-dec-21-2009.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/5772925658043230786'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/5772925658043230786'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2009/12/today-rubyspec-dec-21-2009.html' title='Today&amp;#39;s RubySpec (Dec 21, 2009)'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-7057758864227863153</id><published>2009-12-21T13:46:00.001-08:00</published><updated>2009-12-21T13:46:12.871-08:00</updated><title type='text'>`String#%` Differs Between Ruby 1.8 and 1.9</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;Try the following code on your ruby.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;p('%-03d' % -5)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The result on &lt;code&gt;ruby 1.8.*&lt;/code&gt; is &lt;code&gt;"-05"&lt;/code&gt; while the result on &lt;code&gt;ruby 1.9.*&lt;/code&gt; is &lt;code&gt;"-5 "&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So, which behavior is correct? The answer is the latter.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;String#%&lt;/code&gt; is subject to be equivalent to &lt;code&gt;sprintf(3)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;"-"&lt;/code&gt; means "left-align"&lt;/li&gt;
&lt;li&gt;&lt;code&gt;"0"&lt;/code&gt; means "completing the spaces with 0" &lt;em&gt;when the alignment is right-align&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, &lt;code&gt;"-0"&lt;/code&gt; is equivalent to mere &lt;code&gt;"-"&lt;/code&gt;. According to the principle, the behavior on &lt;code&gt;ruby 1.8&lt;/code&gt; is wrong.&lt;/p&gt;

&lt;p&gt;(I think that the reason why ruby core developers don't change the 1.8's behavior is that the change may break existing codes.)&lt;/p&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-7057758864227863153?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/7057758864227863153/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2009/12/string-differs-between-ruby-18-and-19.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/7057758864227863153'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/7057758864227863153'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2009/12/string-differs-between-ruby-18-and-19.html' title='`String#%` Differs Between Ruby 1.8 and 1.9'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-7012935221852742297</id><published>2009-12-20T16:44:00.001-08:00</published><updated>2009-12-20T16:44:57.734-08:00</updated><title type='text'>Efficient Software-Based Fault Isolation</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;Paper(pdf): &lt;a href='http://crypto.stanford.edu/cs155/papers/sfi.pdf'&gt;http://crypto.stanford.edu/cs155/papers/sfi.pdf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Discussion: &lt;a href='http://papersincomputerscience.org/2009/12/19/efficient-software-based-fault-isolation/'&gt;http://papersincomputerscience.org/2009/12/19/efficient-software-based-fault-isolation/&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Citation: Wahbe, R., Lucco, S., Anderson, T. E., and Graham, S. L. 1993. Efficient software-based fault isolation. In Proceedings of the Fourteenth ACM Symposium on Operating Systems Principles (Asheville, North Carolina, United States, December 05 – 08, 1993). SOSP ‘93. ACM, New York, NY, 203-216. (PS) (PDF)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This paper is in December 1993; 16 years ago.
This paper discusses how to &lt;em&gt;isolate&lt;/em&gt; a system failure without using any special hardwares. For example, how to impound a bug within the process is important because nobody expects that a bug of a game which is working on a system causes the whole system to crash.&lt;/p&gt;

&lt;p&gt;This paper explains the approach with the following subsections.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Segment Matching&lt;/li&gt;
&lt;li&gt;Address Sandboxing&lt;/li&gt;
&lt;li&gt;Optimizations&lt;/li&gt;
&lt;li&gt;Process Resources&lt;/li&gt;
&lt;li&gt;Data Sharing&lt;/li&gt;
&lt;li&gt;Implementation and Verification&lt;/li&gt;
&lt;/ul&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-7012935221852742297?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/7012935221852742297/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2009/12/efficient-software-based-fault.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/7012935221852742297'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/7012935221852742297'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2009/12/efficient-software-based-fault.html' title='Efficient Software-Based Fault Isolation'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-8382361479190155219</id><published>2009-12-20T13:33:00.001-08:00</published><updated>2009-12-21T03:06:18.689-08:00</updated><title type='text'>Yacc, JavaCC and Racc</title><content type='html'>&lt;p&gt;To compare the three parser generators, here I'll show an easy
sample written in them.&lt;/p&gt;

&lt;h2&gt;Target Syntax&lt;/h2&gt;

&lt;p&gt;The following codes are accepted.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&amp;quot;&lt;code&gt;1+2&lt;/code&gt;&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;&lt;code&gt;23423423432 + 923401&lt;/code&gt;&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;&lt;code&gt;23432      + 2&lt;/code&gt;&amp;quot;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The compiler will calculate the single addition and shows the
value.&lt;/p&gt;

&lt;p&gt;The following codes aren't accepted.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&amp;quot;&lt;code&gt;1+2+3&lt;/code&gt;&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;&lt;code&gt;1-2&lt;/code&gt;&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;&lt;code&gt;1+&lt;/code&gt;&amp;quot;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;JavaCC&lt;/h2&gt;

&lt;p&gt;The following code is from
&lt;a href="http://i.loveruby.net/ja/stdcompiler/"&gt;Standard Compiler&lt;/a&gt; by
Minero Aoki.&lt;/p&gt;

&lt;p&gt;The filename is &lt;code&gt;A.jj&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;PARSER_BEGIN(A)
import java.io.*;

class A {
  static public void main(String[] args) {
    for (String arg : args) {
      try {
        System.out.println(evaluate(arg));
      }
      catch (ParseException ex) {
        System.err.println(ex.getMessage());
      }
    }
  }

  static public long evaluate(String src) throws ParseException {
    Reader reader = new StringReader(src);
    return new A(reader).expr();
  }
}
PARSER_END(A)

SKIP: { &amp;lt;[&amp;quot; &amp;quot;, &amp;quot;\t&amp;quot;, &amp;quot;\r&amp;quot;, &amp;quot;\n&amp;quot;]&amp;gt; }

TOKEN: {
  &amp;lt;INTEGER: ([&amp;quot;0&amp;quot;-&amp;quot;9&amp;quot;])+&amp;gt;
}

long expr():
{
  Token x, y;
}
{
  x=&amp;lt;INTEGER&amp;gt; &amp;quot;+&amp;quot; y=&amp;lt;INTEGER&amp;gt; &amp;lt;EOF&amp;gt;
    {
      return Long.parseLong(x.image) + Long.parseLong(y.image);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To run this, type the following commends&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ javacc A.jj
$ javac A.java
$ java A '1 +  3'
4
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This build process produces the following files automatically.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A.class&lt;/li&gt;
&lt;li&gt;A.java&lt;/li&gt;
&lt;li&gt;AConstants.class&lt;/li&gt;
&lt;li&gt;AConstants.java&lt;/li&gt;
&lt;li&gt;ATokenManager.class&lt;/li&gt;
&lt;li&gt;ATokenManager.java&lt;/li&gt;
&lt;li&gt;ParseException.class&lt;/li&gt;
&lt;li&gt;ParseException.java&lt;/li&gt;
&lt;li&gt;SimpleCharStream.class&lt;/li&gt;
&lt;li&gt;SimpleCharStream.java&lt;/li&gt;
&lt;li&gt;Token.class&lt;/li&gt;
&lt;li&gt;Token.java&lt;/li&gt;
&lt;li&gt;TokenMgrError.class&lt;/li&gt;
&lt;li&gt;TokenMgrError.java&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Yacc and Lex&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;a.y&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;%token NUMBER

%%

expr : NUMBER '+' NUMBER { printf(&amp;quot;%d&amp;quot;, $1 + $3); }

%%
#include &amp;lt;stdio.h&amp;gt;
#include &amp;quot;lex.yy.c&amp;quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;a.l&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;%{
#include &amp;quot;a.tab.h&amp;quot;
%}
%%
[0-9]+    {sscanf(yytext,&amp;quot;%d&amp;quot;,&amp;amp;yylval); return(NUMBER);}
[ \r\n\t]   ;
.         return(yytext[0]);
%%
#ifndef yywrap
yywrap() { return 1; }
#endif
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;run&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ bison -d a.y &amp;amp;&amp;amp; lex a.l
$ gcc a.tab.c -ly -ll
$ ./a.out
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;files automatically generated&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a.out&lt;/li&gt;
&lt;li&gt;a.tab.c&lt;/li&gt;
&lt;li&gt;a.tab.h&lt;/li&gt;
&lt;li&gt;lex.yy.c&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Racc&lt;/h2&gt;

&lt;p&gt;I referred this blog entry
&lt;a href="http://d.hatena.ne.jp/morphine57/20090824/1251129740"&gt;http://d.hatena.ne.jp/morphine57/20090824/1251129740&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;a.racc&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class A
  token NUM
rule
   expr : NUM '+' NUM { result = val[0] + val[2] }
end
---- header
require 'strscan'
---- inner
  def parse(str)
    @tokens = []
    s = StringScanner.new(str)
    until s.eos?
      case
      when s.scan(/[0-9]+/)
        @tokens &amp;lt;&amp;lt; [:NUM, s[0].to_i]
      when s.skip(/[ \t\r\n]/)
      else
        @tokens &amp;lt;&amp;lt; [s.getch, nil]
      end
    end
    do_parse()
  end

  def next_token
    @tokens.shift
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And runs&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ racc a.racc
$ ruby192 -r ./a.tab.rb -e 'p A.new.parse &amp;quot;1+ 2&amp;quot;'
3
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Files automatically generated&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a.tab.rb&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Statistics&lt;/h2&gt;

&lt;p&gt;The lines of code which I have to write by myself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JavaCC: 39&lt;/li&gt;
&lt;li&gt;Yacc: 9 + 11&lt;/li&gt;
&lt;li&gt;Racc: 26&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The lines of code which are automatically generated:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JavaCC: 1446&lt;/li&gt;
&lt;li&gt;Yacc: 3280&lt;/li&gt;
&lt;li&gt;Racc: 117 (assuming the gem library &lt;code&gt;racc&lt;/code&gt; is already
installed)&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-8382361479190155219?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/8382361479190155219/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2009/12/yacc-javacc-and-racc.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/8382361479190155219'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/8382361479190155219'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2009/12/yacc-javacc-and-racc.html' title='Yacc, JavaCC and Racc'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-8909623675057223578</id><published>2009-12-18T16:53:00.001-08:00</published><updated>2009-12-18T16:53:17.651-08:00</updated><title type='text'>Trying to Install JavaCC (Java Compiler Compiler)</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;pre&gt;&lt;code&gt;$ sudo port install javacc
---&amp;gt;  Computing dependencies for readline
---&amp;gt;  Fetching readline
---&amp;gt;  Attempting to fetch readline-6.0.tar.gz from http://mirrors.ibiblio.org/pub/mirrors/gnu/ftp/gnu/readline
---&amp;gt;  Verifying checksum(s) for readline
---&amp;gt;  Extracting readline
---&amp;gt;  Applying patches to readline
---&amp;gt;  Configuring readline
---&amp;gt;  Building readline
---&amp;gt;  Staging readline into destroot
---&amp;gt;  Deactivating readline @6.0.000_1
---&amp;gt;  Computing dependencies for readline
---&amp;gt;  Installing readline @6.0.000_2+darwin
---&amp;gt;  Activating readline @6.0.000_2+darwin
---&amp;gt;  Cleaning readline
---&amp;gt;  Computing dependencies for sqlite3
---&amp;gt;  Fetching sqlite3
---&amp;gt;  Attempting to fetch sqlite-3.6.21.tar.gz from http://www.sqlite.org/
---&amp;gt;  Verifying checksum(s) for sqlite3
---&amp;gt;  Extracting sqlite3
---&amp;gt;  Configuring sqlite3
---&amp;gt;  Building sqlite3
---&amp;gt;  Staging sqlite3 into destroot
---&amp;gt;  Deactivating sqlite3 @3.6.16_0
---&amp;gt;  Computing dependencies for sqlite3
---&amp;gt;  Installing sqlite3 @3.6.21_0
---&amp;gt;  Activating sqlite3 @3.6.21_0
---&amp;gt;  Cleaning sqlite3
---&amp;gt;  Computing dependencies for javasqlite
---&amp;gt;  Fetching javasqlite
---&amp;gt;  Attempting to fetch javasqlite-20060714.tar.gz from http://www.ch-werner.de/javasqlite/
---&amp;gt;  Verifying checksum(s) for javasqlite
---&amp;gt;  Extracting javasqlite
---&amp;gt;  Applying patches to javasqlite
---&amp;gt;  Configuring javasqlite
---&amp;gt;  Building javasqlite
Error: Target org.macports.build returned: shell command " cd "/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_ports_java_javasqlite/work/javasqlite-20060714" &amp;amp;&amp;amp; /usr/bin/make -j1 all " returned error 2
Command output: /usr/bin/javac -nowarn  SQLite/Authorizer.java
/usr/bin/javac -nowarn  SQLite/BusyHandler.java
/usr/bin/javac -nowarn  SQLite/Callback.java
/usr/bin/javac -nowarn  SQLite/Database.java
Note: ./SQLite/TableResult.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
/usr/bin/javac -nowarn  SQLite/Shell.java
./libtool /usr/bin/gcc-4.0 -I/opt/local/include -I/opt/local/include \
            -DHAVE_SQLITE2=1 -DHAVE_SQLITE3=1 \
            -o native/mkconst native/mkconst.c /opt/local/lib/libsqlite.la /opt/local/lib/libsqlite3.la
libtool: warning: cannot infer operation mode from `/usr/bin/gcc-4.0'
libtool: you must specify a MODE
Try `libtool --help' for more information.
make: *** [native/mkconst] Error 1

Error: Status 1 encountered during processing.
/opt/local/var/macports/sources/rsync.macports.org/release/ports
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;readline, sqlite3, javasqlite... What was happening? I just wanted to install JavaCC...&lt;/p&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-8909623675057223578?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/8909623675057223578/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2009/12/trying-to-install-javacc-java-compiler.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/8909623675057223578'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/8909623675057223578'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2009/12/trying-to-install-javacc-java-compiler.html' title='Trying to Install JavaCC (Java Compiler Compiler)'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-9184411530586731780</id><published>2009-12-18T14:32:00.001-08:00</published><updated>2009-12-18T14:33:06.887-08:00</updated><title type='text'>RubyConf 2009 Was Great</title><content type='html'>&lt;p&gt;I had been staying in Burlingame, California to attend &lt;a href="http://rubyconf.org/"&gt;RubyConf 2009&lt;/a&gt; and &lt;a href="http://jrubyconf.com/"&gt;JRubyConf 2009&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://farm3.static.flickr.com/2680/4118539200_fbabe6747a.jpg" alt="rooms" /&gt;
&lt;img src="http://farm3.static.flickr.com/2678/4117768699_85c64fd1b7.jpg" alt="matz keynote" /&gt;
&lt;img src="http://farm3.static.flickr.com/2748/4119520821_d83ae67a50.jpg" alt="breakfast" /&gt;
&lt;img src="http://farm3.static.flickr.com/2758/4118537624_936150de8c.jpg" alt="aisle" /&gt;
&lt;img src="http://farm3.static.flickr.com/2659/4120169785_4874fbcaf3.jpg" alt="people" /&gt;
&lt;img src="http://farm3.static.flickr.com/2622/4128565628_1c2cd1f4e5.jpg" alt="by tmaedax" /&gt;
&lt;img src="http://gyazo.com/99daa5cf4655074748de2d6cf5fa89a1.png" alt="Matz eatz breakfast alone" /&gt;&lt;/p&gt;

&lt;p&gt;I made two presentations there in English.&lt;/p&gt;

&lt;h2&gt;&amp;quot;Hacking parse.y&amp;quot;&lt;/h2&gt;

&lt;p&gt;First, I made 45 minutes presentation in English there.&lt;/p&gt;

&lt;div style="width:425px;text-align:left" id="__ss_2549033"&gt;&lt;a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/ujihisa/hacking-parsey-rubyconf-2009" title="Hacking parse.y (RubyConf 2009)"&gt;Hacking parse.y (RubyConf 2009)&lt;/a&gt;&lt;object style="margin:0px" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=hackingparse-yrubyconf2009-091120160616-phpapp02&amp;stripped_title=hacking-parsey-rubyconf-2009" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=hackingparse-yrubyconf2009-091120160616-phpapp02&amp;stripped_title=hacking-parsey-rubyconf-2009" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;"&gt;View more &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/"&gt;documents&lt;/a&gt; from &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/ujihisa"&gt;ujihisa&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I talked about the parser part of MRI (Matz Ruby Implementation) with demonstrations including adding new syntaxes.&lt;/p&gt;

&lt;p&gt;(I wouldn't like to say something negative, but I have to say that my presentation wasn't as well as I expected.
I think the reasons were that I was sick at the time and I needed more safety nets of my demonstration.)&lt;/p&gt;

&lt;h2&gt;&amp;quot;Termtter the ultimate twitter client&amp;quot;&lt;/h2&gt;

&lt;p&gt;Second, I made 5 minutes short talk there.&lt;/p&gt;

&lt;div style="width:425px;text-align:left" id="__ss_2557295"&gt;&lt;a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/ujihisa/rubyconf-2009-lt-termtter" title="RubyConf 2009 LT &amp;quot;Termtter&amp;quot;"&gt;RubyConf 2009 LT &amp;quot;Termtter&amp;quot;&lt;/a&gt;&lt;object style="margin:0px" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=rubyconflttermtter-091122030721-phpapp01&amp;stripped_title=rubyconf-2009-lt-termtter" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=rubyconflttermtter-091122030721-phpapp01&amp;stripped_title=rubyconf-2009-lt-termtter" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;"&gt;View more &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/ujihisa"&gt;ujihisa&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This slides were made by jugyo. He tried to make presentation, but he was so afraid of his English that he asked me to make it instead. So I did.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://farm3.static.flickr.com/2489/4127346217_50d65ae268.jpg" alt="LT; photo taken by kakutani" /&gt;&lt;/p&gt;

&lt;p&gt;My roommates.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://farm3.static.flickr.com/2602/4128134848_c211b14fef.jpg" alt="roommates; Photo taken by kakutani" /&gt;&lt;/p&gt;

&lt;h2&gt;JRubyConf 2009&lt;/h2&gt;

&lt;p&gt;I also attended JRubyConf 2009 the day after RubyConf 2009. I really wanted to attend all sessions, but I couldn't because my body condition was worst at the time.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://gyazo.com/9fa662ad00aed2befcef99a634470dec.png" alt="1" /&gt;
&lt;img src="http://gyazo.com/e986a0c13efd3d3e0c0bf5ff5dd2501b.png" alt="2" /&gt;&lt;/p&gt;

&lt;h2&gt;My Personal Impression&lt;/h2&gt;

&lt;h3&gt;Small But Important Events&lt;/h3&gt;

&lt;p&gt;I went to Engine Yard twice. I went to eat lunch and dinner with great programmers. I talked a lot. I gave some presents to some people, and I got great things by them as well.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://farm3.static.flickr.com/2526/4128579410_b14b783f7a.jpg" alt="rubyspec conf; photo taken by tmaedax" /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="http://gyazo.com/1105850fdaae5dcbf41f8035460c95de.png" alt="the Last Supper" /&gt;&lt;/p&gt;

&lt;h3&gt;English&lt;/h3&gt;

&lt;p&gt;I was surprised to notice that I was starting to feel as comfortable with English as with Japanese.
A few years ago, English was kind of cryptic language for me.
To use English, I had to think a lot like calculating. I had to think and translate before I could understand what I was listening to.&lt;/p&gt;

&lt;p&gt;When I lived in Canada, I didn't notice that I had stopped doing that.
Maybe because my improvement was too gradual to be noticed.
My one month stay in Japan made me realize this fact.&lt;/p&gt;

&lt;p&gt;It's exciting. Even though I still can't speak English fluently or listen to English without having difficulties, but at least, now I don't feel like using English is so difficult.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://gyazo.com/8113278fe60e9fabc7be8b2a38278f54.png" alt="Transit at Salt Lake City" /&gt;&lt;/p&gt;

&lt;h2&gt;Links&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Tim Bray's blog &lt;a href="http://www.tbray.org/ongoing/When/200x/2009/11/21/RubyConf-2009"&gt;http://www.tbray.org/ongoing/When/200x/2009/11/21/RubyConf-2009&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;You can find me in the first photo.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.ruby-mine.de/2009/11/22/rubyconf2009-tag-1/"&gt;http://www.ruby-mine.de/2009/11/22/rubyconf2009-tag-1/&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;There's a comment of my presentation of &amp;quot;hacking parse.y&amp;quot;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="http://gyazo.com/a375a29d59e8f2b0ecf7b540e351c25b.png" alt="stanford" /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-9184411530586731780?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/9184411530586731780/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2009/12/rubyconf-2009-was-great.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/9184411530586731780'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/9184411530586731780'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2009/12/rubyconf-2009-was-great.html' title='RubyConf 2009 Was Great'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm3.static.flickr.com/2680/4118539200_fbabe6747a_t.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-3535005715967833662</id><published>2009-12-18T13:27:00.001-08:00</published><updated>2009-12-18T13:35:45.497-08:00</updated><title type='text'>Left Hand Values in Ruby</title><content type='html'>&lt;p&gt;Local variables, Constants, Instance variables, Class variables and global variables&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;a = 1
A = 1
@a = 1
@@a = 1
$a = 1
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Arefs and Attributes&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;a[:b] = 1
# a.[](:b, 1)

a.b = 1
a::b = 1
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Combine&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;a, A, @a, @@a, $a, a[:b], a.b =
  1, 1, 1, 1, 1, 1, 1
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Opassign&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;a += 1
# a, b += 1, 2  raises Syntax Error!
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The only one syntax which allows to write expression in left hand sides is aref. For example, &lt;code&gt;a[random(10)] = 1&lt;/code&gt; is accepted. Also, I can write such codes:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;alias []= instance_variable_set
alias [] instance_variable_get

a = Object.new
a['@a'] = 1
p a['@a'] #=&amp;gt; 1
p a #=&amp;gt; #&amp;lt;Object:0x40afb0 @a=1&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-3535005715967833662?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/3535005715967833662/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2009/12/left-hand-values-in-ruby.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/3535005715967833662'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/3535005715967833662'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2009/12/left-hand-values-in-ruby.html' title='Left Hand Values in Ruby'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-8591912536206631673</id><published>2009-12-03T12:15:00.001-08:00</published><updated>2009-12-03T12:15:37.534-08:00</updated><title type='text'>Termtter Installs New Gem Libraries Automatically</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;I wrote a new &lt;a href='http://termtter.org/'&gt;termtter&lt;/a&gt; plugin.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://github.com/jugyo/termtter/blob/dbbd3d1b16933a205470125982f03a3444de3d07/lib/plugins/gem_install.rb'&gt;http://github.com/jugyo/termtter/blob/dbbd3d1b16933a205470125982f03a3444de3d07/lib/plugins/gem_install.rb&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you use this plugin by &lt;code&gt;plug gem_install&lt;/code&gt;, your termtter will install arbitrary gem libraries when they appeared on your timeline, replies or anything on your termtter. How useful it is. If you already have &lt;code&gt;g&lt;/code&gt;, the automatic installation will be announced on your Growl.&lt;/p&gt;

&lt;p&gt;The plugin needs more fixes and spec.&lt;/p&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-8591912536206631673?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/8591912536206631673/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2009/12/termtter-installs-new-gem-libraries.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/8591912536206631673'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/8591912536206631673'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2009/12/termtter-installs-new-gem-libraries.html' title='Termtter Installs New Gem Libraries Automatically'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-6247132697790739404</id><published>2009-12-01T00:00:00.000-08:00</published><updated>2009-11-30T03:11:33.340-08:00</updated><title type='text'>Write Implementation and Spec on the Same File</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;-- For &lt;a href='http://atnd.org/events/2351'&gt;http://atnd.org/events/2351&lt;/a&gt; day 1&lt;/p&gt;

&lt;p&gt;Sometimes it would be preferable to write the implementation and the specific on the same single file because of the reasons including ease of maintenance and ease of distribution.
The following snippet will be helpful for the purpose.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/usr/bin/env ruby

{implementation}

case $0
when __FILE__
  {command line interface of the implementation}
when /spec[^/]*$/
  {spec of the implementation}
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For example, assuming &lt;code&gt;a.rb&lt;/code&gt; is that you've written with using the template,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ruby a.rb&lt;/code&gt; runs &lt;code&gt;{implementation}&lt;/code&gt; and &lt;code&gt;{command line interface of the implementation}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;./a.rb&lt;/code&gt; runs &lt;code&gt;{implementation}&lt;/code&gt; and &lt;code&gt;{command line interface of the implementation}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec a.rb&lt;/code&gt; runs &lt;code&gt;{implementation}&lt;/code&gt; and &lt;code&gt;{spec of the implementation}&lt;/code&gt; with RSpec&lt;/li&gt;
&lt;li&gt;&lt;code&gt;require 'a'&lt;/code&gt; in other scripts runs only &lt;code&gt;{implementation}&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-6247132697790739404?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/6247132697790739404/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2009/11/write-implementation-and-spec-on-same.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/6247132697790739404'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/6247132697790739404'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2009/11/write-implementation-and-spec-on-same.html' title='Write Implementation and Spec on the Same File'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-5660004187163734416</id><published>2009-11-28T20:45:00.001-08:00</published><updated>2009-11-29T10:33:05.553-08:00</updated><title type='text'>Trying Stomp and Stompserver on Ruby</title><content type='html'>&lt;p&gt;STOMP: Streaming Text Orientated Messaging Protocol is getting important, particularly for web programmers who need to think scalability.
There are Ruby implementations of STOMP, called &lt;code&gt;stomp&lt;/code&gt; and &lt;code&gt;stompserver&lt;/code&gt;.
Here is the brief introduction of them.&lt;/p&gt;

&lt;h2&gt;INSTALL&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;$ gem install stomp
$ gem install stompserver
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Currently it is reported that &lt;code&gt;stompserver&lt;/code&gt; cannot be installed well on ruby 1.9. I don't know why so far.&lt;/p&gt;

&lt;h2&gt;HELLO, WORLD&lt;/h2&gt;

&lt;p&gt;Get three terminals ready.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[Terminal 1]$ mkdir tmp &amp;amp;&amp;amp; cd tmp
[Terminal 1]$ stompserver

[Terminal 2]$ irb -rubygems
&amp;gt; require 'stomp'
&amp;gt; Stomp::Client.new.subscribe('/a/b') {|m| p m.body }

[Terminal 3]$ irb -rubygems
&amp;gt; require 'stomp'
&amp;gt; Stomp::Client.new.send('/a/b', 'Hello, world!')
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And then check your terminal 2.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;stompserver&lt;/code&gt; creates &lt;code&gt;etc&lt;/code&gt; and &lt;code&gt;log&lt;/code&gt; directories on the current directly and opens port 61613.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-5660004187163734416?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/5660004187163734416/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2009/11/trying-stomp-and-stompserver-on-ruby.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/5660004187163734416'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/5660004187163734416'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2009/11/trying-stomp-and-stompserver-on-ruby.html' title='Trying Stomp and Stompserver on Ruby'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-2287644969240588843</id><published>2009-11-19T13:27:00.001-08:00</published><updated>2009-11-19T13:27:19.297-08:00</updated><title type='text'>I'm Attending RubyConf 2009</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;Now I'm staying at a hotel near San Francisco Airport where RubyConf 2009 will be held on Nov 19 to 21 and JRubyConf on Nov 22 as well.&lt;/p&gt;

&lt;h2&gt;As an attendee&lt;/h2&gt;

&lt;p&gt;This is my first time to attend a conference not in Japan.
I had lived in Vancouver, Canada for a half year, so now I can speak and listen English better than last year, but I still feel difficulty in using English, particularly in listening.
Also, I'm shy and nervous.&lt;/p&gt;

&lt;p&gt;If you find &lt;a href='http://gyazo.com/a830179c702431e3b228ef65455586a0.png'&gt;such person&lt;/a&gt;, feel free to talk to him. It's me.
I may have a nameplate that is written "ujihisa".&lt;/p&gt;

&lt;h2&gt;As a speaker&lt;/h2&gt;

&lt;p&gt;I'll talk about Ruby's parser.
The presentation will be not for a great Ruby hacker, but for an ordinary programmer.&lt;/p&gt;

&lt;p&gt;If you are interested in my presentation, I highly recommend you to build the Ruby trunk in advance. It's easy but takes long time.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ mkdir ~/rubies
$ svn co (ruby trunk)
$ cd (the directory)
$ ./configure --prefix=$HOME/rubies
$ make
$ make install
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;As a Japanese&lt;/h2&gt;

&lt;p&gt;If you are interested in Japanese culture, feel free to ask me about it as well as about Ruby.&lt;/p&gt;

&lt;h2&gt;Contact&lt;/h2&gt;

&lt;p&gt;&lt;a href='http://twitter.com/ujm'&gt;http://twitter.com/ujm&lt;/a&gt;&lt;/p&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-2287644969240588843?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/2287644969240588843/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2009/11/i-attending-rubyconf-2009.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/2287644969240588843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/2287644969240588843'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2009/11/i-attending-rubyconf-2009.html' title='I&amp;#39;m Attending RubyConf 2009'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-3799143128285578955</id><published>2009-11-18T08:04:00.001-08:00</published><updated>2009-11-18T08:04:07.820-08:00</updated><title type='text'>Playing with JRuby's Parser</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;Apply this patch to JRuby.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;diff --git a/src/org/jruby/lexer/yacc/RubyYaccLexer.java b/src/org/jruby/lexer/yacc/RubyYaccLexer.java
index dd1733e..dc591a2 100644
--- a/src/org/jruby/lexer/yacc/RubyYaccLexer.java
+++ b/src/org/jruby/lexer/yacc/RubyYaccLexer.java
@@ -1208,6 +1208,12 @@ public class RubyYaccLexer {
     private int colon(boolean spaceSeen) throws IOException {
         int c = src.read();

+        if (c == '-' &amp;amp;&amp;amp; src.peek(')')) {
+          src.read();
+          lex_state = LexState.EXPR_BEG;
+          yaccValue = new Token("=&amp;gt;", getPosition());
+          return Tokens.tASSOC;
+        }
         if (c == ':') {
             if (isBEG() || lex_state == LexState.EXPR_CLASS || (isARG() &amp;amp;&amp;amp; spaceSeen)) {
                 lex_state = LexState.EXPR_BEG;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now you can write &lt;code&gt;:-)&lt;/code&gt; as &lt;code&gt;=&amp;gt;&lt;/code&gt; in braces as Hash literals.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ./bin/jruby ./bin/jirb
&amp;gt; {1 =&amp;gt; 2}
=&amp;gt; {1=&amp;gt;2}
&amp;gt; {1 :-) 2}
=&amp;gt; {1=&amp;gt;2}
&amp;gt; {:aaa =&amp;gt; :bbb}
=&amp;gt; {:aaa=&amp;gt;:bbb}
&amp;gt; {:aaa:-):bbb}
=&amp;gt; {:aaa=&amp;gt;:bbb}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This patch is almost same as my previous patch to MRI.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;diff --git a/parse.y b/parse.y
index b8d9b59..a592aed 100644
--- a/parse.y
+++ b/parse.y
@@ -7125,6 +7125,11 @@ parser_yylex(struct parser_params *parser)

       case ':':
         c = nextc();
+        if (c == '-' &amp;amp;&amp;amp; peek(')') {
+            nextc();
+            lex_state = EXPR_BEG;
+            return tASSOC;
+        }
         if (c == ':') {
             if (IS_BEG() ||
                 lex_state == EXPR_CLASS || (IS_ARG() &amp;amp;&amp;amp; space_seen)) {
&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-3799143128285578955?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/3799143128285578955/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2009/11/playing-with-jruby-parser.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/3799143128285578955'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/3799143128285578955'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2009/11/playing-with-jruby-parser.html' title='Playing with JRuby&amp;#39;s Parser'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-4759922413072117013</id><published>2009-11-18T06:50:00.001-08:00</published><updated>2009-11-18T06:50:45.532-08:00</updated><title type='text'>One Month In Japan</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;I had been in Japan for a month until yesterday. I went to my parents' home, did things related to my admission to the graduate universities, attended some conferences and workshops, and met many friends.&lt;/p&gt;

&lt;p&gt;List of workshops I attended:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;uuuu&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Kansai Ruby Workshop #38&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vim Workshop #4&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LiveCoing#7&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Kansai Ruby Kaigi #2 at Kansai Open Forum 2009&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Working Effectively with Legacy Code" Study Group&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Golang Hackathon&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;xUnit Workshop&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tokyo Rails Workshop #45&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I made presentations at the workshops, mostly about &lt;code&gt;parse.y&lt;/code&gt; of Ruby.&lt;/p&gt;

&lt;p&gt;Other events:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Professor Konami and his students&lt;/li&gt;
&lt;li&gt;Big Buddha&lt;/li&gt;
&lt;li&gt;Hoso Hackathon&lt;/li&gt;
&lt;li&gt;SVTour Alumni Party&lt;/li&gt;
&lt;li&gt;Teppan lunch&lt;/li&gt;
&lt;li&gt;ujihkn&lt;/li&gt;
&lt;li&gt;Ramen Hackathon&lt;/li&gt;
&lt;li&gt;Todai Hackathon&lt;/li&gt;
&lt;li&gt;ujihkn&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;My Sincerely Friends&lt;/h2&gt;

&lt;p&gt;I feel too thankful for my sincerely friends to say thank you. I proud them.
May luck with you!&lt;/p&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-4759922413072117013?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/4759922413072117013/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2009/11/one-month-in-japan.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/4759922413072117013'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/4759922413072117013'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2009/11/one-month-in-japan.html' title='One Month In Japan'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-2259648066960158568</id><published>2009-11-12T06:53:00.001-08:00</published><updated>2009-11-12T06:53:35.018-08:00</updated><title type='text'>RubyConf 2009 Schedule</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;&lt;img alt='shot' src='http://gyazo.com/5d5c011d8e669bacdedf1f3ddecf86a5.png'/&gt;&lt;/p&gt;

&lt;p&gt;My talk "Hacking parse.y" will be on Thursday Nov. 18 which is the first day of RubyConf 2009.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://rubyconf.org/pages/schedule'&gt;http://rubyconf.org/pages/schedule&lt;/a&gt;&lt;/p&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-2259648066960158568?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/2259648066960158568/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2009/11/rubyconf-2009-schedule.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/2259648066960158568'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/2259648066960158568'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2009/11/rubyconf-2009-schedule.html' title='RubyConf 2009 Schedule'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-8081521667958856138</id><published>2009-11-04T01:00:00.001-08:00</published><updated>2009-11-04T01:00:39.557-08:00</updated><title type='text'>Accepting Both Get And Post Method in Sinatra</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;Whe you would like to accept both GET and POST request with the same block, use the following &lt;code&gt;get_or_post&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;[Before]&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'rubygems'
require 'sinatra'

get '/' do
  'hi'
end

post '/' do
  'hi'
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;[AFTER]&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'rubygems'
require 'sinatra'

def get_or_post(path, opts={}, &amp;amp;block)
  get(path, opts, &amp;amp;block)
  post(path, opts, &amp;amp;block)
end

get_or_post '/' do
  'hi'
end
&lt;/code&gt;&lt;/pre&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-8081521667958856138?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/8081521667958856138/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2009/11/accepting-both-get-and-post-method-in.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/8081521667958856138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/8081521667958856138'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2009/11/accepting-both-get-and-post-method-in.html' title='Accepting Both Get And Post Method in Sinatra'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-4839117599674373626</id><published>2009-11-01T03:09:00.001-08:00</published><updated>2009-11-01T03:09:15.059-08:00</updated><title type='text'>4th Vim Workshop at Osaka</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;&lt;a href='http://atnd.org/events/1797'&gt;http://atnd.org/events/1797&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Today I attended a workshop about Vim. Originally I started the workshop, and &lt;a href='http://twitter.com/kozo_ni'&gt;kozo_ni&lt;/a&gt; took over from the workshop and the soul.&lt;/p&gt;

&lt;p&gt;The number of the attendees were 10, including a person from far Yokohama.&lt;/p&gt;

&lt;p&gt;Presentations of the workshop were &lt;a href='http://ustream.tv/channel/kozo-ni'&gt;broadcast on ustream&lt;/a&gt;. Some presentations were recorded.&lt;/p&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-4839117599674373626?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/4839117599674373626/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2009/11/4th-vim-workshop-at-osaka.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/4839117599674373626'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/4839117599674373626'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2009/11/4th-vim-workshop-at-osaka.html' title='4th Vim Workshop at Osaka'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-2088731203004986878</id><published>2009-10-30T08:11:00.001-07:00</published><updated>2009-10-31T04:49:53.635-07:00</updated><title type='text'>38th Kansai Ruby Workshop</title><content type='html'>&lt;p&gt;&lt;a href="http://jp.rubyist.net/?KansaiWorkshop38"&gt;http://jp.rubyist.net/?KansaiWorkshop38&lt;/a&gt;
(in Japanese)&lt;/p&gt;

&lt;p&gt;I attended
&lt;a href="http://jp.rubyist.net/?KansaiWorkshop38"&gt;38th Kansai Ruby Workshop&lt;/a&gt;
today and make a presentation there. The workshop was
&lt;a href="http://jp.rubyist.net/?KansaiWorkshopUstream"&gt;ustreamed&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;My Presentation &amp;quot;Hacking parse.y&amp;quot;&lt;/h2&gt;

&lt;p&gt;I have made the same title presentation in Vancouver.rb so far. I
also have two other opportunities to make the same title
presentation in Kansai Open Forum and RubyConf2009. All
presentations are different because of the difference audience.
Kansai Ruby Workshop is the most casual place of them, so my
presentation today was be the most casual one.&lt;/p&gt;

&lt;p&gt;The agenda was the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Brief self introduction&lt;/li&gt;
&lt;li&gt;What is Ruby Core&lt;/li&gt;
&lt;li&gt;What is Ruby's parser&lt;/li&gt;
&lt;li&gt;Understanding colons&lt;/li&gt;
&lt;li&gt;Adding literal&lt;/li&gt;
&lt;li&gt;(cont.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that this presentation &lt;em&gt;isn't&lt;/em&gt; for super Ruby programmers. I
think all ruby commitors already know all of what I'll talk
tomorrow.&lt;/p&gt;

&lt;h2&gt;Slides, Handouts and Record&lt;/h2&gt;

&lt;p&gt;Slides are available &lt;a href="http://www.slideshare.net/ujihisa/hacking-parsey-rubykansai38"&gt;here(slideshare)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Handouts are availabble
&lt;a href="http://jp.rubyist.net/?c=plugin;plugin=attach_download;p=KansaiWorkshop38;file_name=handout_hacking_parsey.pdf"&gt;here(pdf)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Record is available &lt;a href="http://www.ustream.tv/recorded/2459758"&gt;here(ustream)&lt;/a&gt;. (in Japanese)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-2088731203004986878?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/2088731203004986878/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2009/10/38th-kansai-ruby-workshop.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/2088731203004986878'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/2088731203004986878'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2009/10/38th-kansai-ruby-workshop.html' title='38th Kansai Ruby Workshop'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-8518900267776976380</id><published>2009-10-14T17:19:00.001-07:00</published><updated>2009-10-14T17:19:58.203-07:00</updated><title type='text'>GRE Exam</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;Today I took the GRE exam.&lt;/p&gt;

&lt;p&gt;The result was too crazy to write here.
I think something must be going wrong.&lt;/p&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-8518900267776976380?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/8518900267776976380/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2009/10/gre-exam.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/8518900267776976380'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/8518900267776976380'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2009/10/gre-exam.html' title='GRE Exam'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-8195518443842020209</id><published>2009-10-08T01:19:00.001-07:00</published><updated>2009-10-08T01:19:33.324-07:00</updated><title type='text'>RubyGems on Ruby 1.9</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;This blog post is a note of a report about the current RubyGems 1.3.5 on Ruby 1.9 for myself (including both 1.9.1 and 1.9.2) without any good reproductions or the solutions.&lt;/p&gt;

&lt;p&gt;When I did &lt;code&gt;rake192 spec&lt;/code&gt; on a directory which contains a Rakefile that uses &lt;code&gt;jeweler&lt;/code&gt;, I met an enormous errors (The suffix means the Ruby version on my machine.)
I've heard that anyhow &lt;code&gt;gem192 uninstall update-rubygems&lt;/code&gt; can solve the problem, so I did it. But after that, the &lt;code&gt;rake192&lt;/code&gt; started to cause segfault!&lt;/p&gt;

&lt;p&gt;The segfault is caused by a 1.9.2 marshal's bug which is already reported but not fixed yet.
I gave up using 1.9.2, and then I decided to use 1.9.1 instead.&lt;/p&gt;

&lt;p&gt;On 1.9.1 the results were exactly same except that it didn't cause a SEGV.&lt;/p&gt;

&lt;h2&gt;Downgrading RubyGems (failed!)&lt;/h2&gt;

&lt;p&gt;According to &lt;a href='http://twitter.com/baroquebobcat/status/4692918454'&gt;baroquebobcat&lt;/a&gt;,&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ gem uninstall rubygems-update
$ gem install -v x.x.x rubygems-update
$ sudo update_rubygems
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;does downgrade rubygems itself. So I did them with some trivial changes, but it failed again.
The following is the result:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ update_rubygems191
&amp;lt;internal:gem_prelude&amp;gt;:344:in `method_missing': undefined method `bin_path' for Gem:Module (NoMethodError)
        from /Users/ujihisa/rubies/bin/update_rubygems191:19:in `&amp;lt;main&amp;gt;'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;hmm...&lt;/p&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-8195518443842020209?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/8195518443842020209/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2009/10/rubygems-on-ruby-19.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/8195518443842020209'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/8195518443842020209'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2009/10/rubygems-on-ruby-19.html' title='RubyGems on Ruby 1.9'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8477445975588753706.post-8893824370175696567</id><published>2009-10-02T23:46:00.001-07:00</published><updated>2009-10-02T23:46:28.423-07:00</updated><title type='text'>What's Your View?</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
      &lt;p&gt;When I was a student, my supervisor often asked me the question. It confused me, which meant that I didn't understand what I was talking.&lt;/p&gt;

&lt;p&gt;Although the relationship between understanding the contents and grasping the view is bi-directionally, it is worth trying to grasp the view of a given research first, then understand the remains. This strategy is easier, particularly for me. Never forget to look for the author's viewpoint. Ask myself: "What's the view of the research?" Now I must be able to find the goal of the research easily.&lt;/p&gt;
    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8477445975588753706-8893824370175696567?l=ujihisa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ujihisa.blogspot.com/feeds/8893824370175696567/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ujihisa.blogspot.com/2009/10/what-your-view.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/8893824370175696567'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8477445975588753706/posts/default/8893824370175696567'/><link rel='alternate' type='text/html' href='http://ujihisa.blogspot.com/2009/10/what-your-view.html' title='What&amp;#39;s Your View?'/><author><name>ujm</name><uri>http://www.blogger.com/profile/08682772434896813808</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_XNWBzEhcpQk/ScTf-JzzdyI/AAAAAAAABV4/qM2EnKz-D-E/S220/Photo+1.jpg'/></author><thr:total>0</thr:total></entry></feed>
