<?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-8555815345499886096</id><updated>2011-07-08T11:20:42.952-07:00</updated><category term='ruby'/><category term='pure'/><category term='slideblast'/><category term='javascript'/><category term='riak'/><category term='erlang'/><category term='webmachine'/><category term='restful'/><category term='gsub'/><category term='beebole'/><category term='template'/><category term='sub'/><category term='pgsql'/><category term='replace'/><category term='rest'/><category term='string'/><category term='jquery'/><category term='stickynotes'/><category term='render'/><category term='mochiweb'/><category term='decode_col'/><category term='web server'/><category term='code'/><category term='webrick'/><category term='nitrogen'/><category term='ubuntu'/><category term='webcandy'/><title type='text'>On Erlang</title><subtitle type='html'>My thoughts and exersizes on this beautiful and powerful language.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://onerlang.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8555815345499886096/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://onerlang.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Serge</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>12</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8555815345499886096.post-93252180746411494</id><published>2010-01-06T07:27:00.000-08:00</published><updated>2010-01-06T07:34:16.900-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nitrogen'/><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='slideblast'/><title type='text'>Nitrogen module fix makes SlideBlast working correctly in IE7.</title><content type='html'>I recently &lt;a href="http://onerlang.blogspot.com/2009/12/how-i-made-slideblast-work-on-my-ubuntu.html"&gt;reported&lt;/a&gt; on a successful SlideBlast presentation server setup. Unfortunately, it worked well only on Firefox and Safari, not on the Internet Explorer. The Z-order is treated differently in the Microsoft browser line than e.g. in Firefox. To make it work correctly in IE, the style parameter&lt;pre&gt;z-index:3&lt;/pre&gt;was added to the &lt;tt&gt;   ./deps/nitrogen/src/elements/layout/element_lightbox.erl&lt;/tt&gt;, so it will look as follows:&lt;br /&gt;&lt;pre&gt;-module (element_lightbox).&lt;br /&gt;&lt;br /&gt;%... skipped ...&lt;br /&gt;&lt;br /&gt;render_element(HtmlID, Record) -&gt;&lt;br /&gt;        Panel = #panel {&lt;br /&gt;                class=lightbox,&lt;br /&gt;                style="position: fixed; top: 0px; left: 0px; bottom: 0px; right: 0px; z-index:3; " &lt;br /&gt;                      ++ wf:to_list(Record#lightbox.style),&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;% ... skipped ...&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Should the fix be applied to the very Nitrogen trunk? It seems reasonable.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8555815345499886096-93252180746411494?l=onerlang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onerlang.blogspot.com/feeds/93252180746411494/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8555815345499886096&amp;postID=93252180746411494' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8555815345499886096/posts/default/93252180746411494'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8555815345499886096/posts/default/93252180746411494'/><link rel='alternate' type='text/html' href='http://onerlang.blogspot.com/2010/01/nitrogen-module-fix-makes-slideblast.html' title='Nitrogen module fix makes SlideBlast working correctly in IE7.'/><author><name>Serge</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8555815345499886096.post-9061492702836880212</id><published>2009-12-27T07:06:00.000-08:00</published><updated>2009-12-27T07:20:39.172-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='riak'/><category scheme='http://www.blogger.com/atom/ns#' term='nitrogen'/><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>How I made the SlideBlast work on my Ubuntu server</title><content type='html'>We want to start with the clean Ubuntu server to test and then run the &lt;a href="http://github.com/rklophaus/SlideBlast"&gt;SlideBlast&lt;/a&gt;, created by &lt;a href="http://rklophaus.com/"&gt;Rusty Klophaus&lt;/a&gt;.&lt;br /&gt;Yes, there is the SlideBlast.com, but we need to have an instance "at home".&lt;br /&gt;So, let us do it! &lt;br /&gt;&lt;br /&gt;We will need the Git,Mercurial to get the codes, and GhostScript and ImageMagick for the SlideBlast. The first lines are needed for Erlang.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;sudo apt-get update&lt;br /&gt;sudo apt-get install libssl-dev libncurses-dev build-essential m4 &lt;br /&gt;sudo apt-get install git-core&lt;br /&gt;sudo apt-get install mercurial&lt;br /&gt;sudo apt-get install ghostscript&lt;br /&gt;sudo apt-get install imagemagick&lt;br /&gt;mkdir ~/src&lt;br /&gt;cd src&lt;br /&gt;&lt;/pre&gt;Riak needs Erlang at least of version 5.7.4, so we need to compile it from the source:&lt;br /&gt;&lt;pre&gt;wget http://erlang.org/download/otp_src_R13B03.tar.gz&lt;br /&gt;tar zxf otp_src_R13B03.tar.gz &lt;br /&gt;cd otp_src_R13B03/&lt;br /&gt;./configure &lt;br /&gt;make&lt;br /&gt;sudo make install&lt;br /&gt;cd ..&lt;br /&gt;&lt;/pre&gt;As of today, the SlideBlast does not work with Riak 0.7 - we need to roll it back a bit.&lt;br /&gt;Let us take the last SlideBlast (with Nitrogen) and the label "riak-0.6" of Riak: &lt;br /&gt;&lt;pre&gt;git clone git://github.com/rklophaus/SlideBlast.git&lt;br /&gt;cd SlideBlast/deps&lt;br /&gt;hg clone http://bitbucket.org/basho/riak&lt;br /&gt;hg update -r riak-0.6&lt;br /&gt;cd ../..&lt;br /&gt;make&lt;br /&gt;./start.sh&lt;br /&gt;&lt;/pre&gt;Now we would be ready to point your browser to http://localhost:8000 and start working.&lt;br /&gt;Hey! What browser? We have Ubuntu Server, running as a virtual guest. Let us make the app visible: edit the &lt;tt&gt;SlideBlast/src/caster_mochiweb_app.erl&lt;/tt&gt; to look like:&lt;br /&gt;&lt;pre&gt;...&lt;br /&gt;%%%Options = [{ip, "127.0.0.1"}, {port, 8000}],  %%% Just this one line to update&lt;br /&gt;   Options = [{ip, "0.0.0.0"}, {port, 8000}],&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;Now we will re-compile it and try it from the host using the proper IP.&lt;br /&gt;&lt;pre&gt;make &lt;br /&gt;./start.sh&lt;br /&gt;&lt;/pre&gt;From the outer box, we will try it as in our case, &lt;tt&gt;http://192.168.1.115:8000&lt;/tt&gt;. &lt;br /&gt;And it worked! &lt;br /&gt;Your IP address of course will be different. &lt;br /&gt;&lt;br /&gt;Word of advice for users: best works on FF, Safari. Chrome and IE show minor glitches, but work too. Best viewed slides have big fonts and little text. The client browser better be open full screen and "f" key is used to use all available browser window space.&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8555815345499886096-9061492702836880212?l=onerlang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onerlang.blogspot.com/feeds/9061492702836880212/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8555815345499886096&amp;postID=9061492702836880212' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8555815345499886096/posts/default/9061492702836880212'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8555815345499886096/posts/default/9061492702836880212'/><link rel='alternate' type='text/html' href='http://onerlang.blogspot.com/2009/12/how-i-made-slideblast-work-on-my-ubuntu.html' title='How I made the SlideBlast work on my Ubuntu server'/><author><name>Serge</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8555815345499886096.post-3849229589459249228</id><published>2009-11-02T18:26:00.000-08:00</published><updated>2009-11-05T10:36:43.386-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='beebole'/><category scheme='http://www.blogger.com/atom/ns#' term='pure'/><category scheme='http://www.blogger.com/atom/ns#' term='jquery'/><category scheme='http://www.blogger.com/atom/ns#' term='template'/><category scheme='http://www.blogger.com/atom/ns#' term='render'/><title type='text'>PURE Version 2 and truly dynamic table rendering.</title><content type='html'>&lt;span style="font-family:arial;font-size:100%;"&gt;&lt;br /&gt;I would like to build a dynamic data-driven Web application.&lt;br /&gt;There is a set of data records and I would like full control over its presentation during the run-time, i.e. customized.&lt;br /&gt;&lt;br /&gt;I came across the Beebole' &lt;a href="http://beebole.com/en/blog/pure/pure-version-2-is-out-for-trial/"&gt;PURE Version 2&lt;/a&gt; rendering engine, which was immediately gaining on me after I made some attempts with the first version of Pure. Here is the short demo just to prove the concept:&lt;br /&gt;&lt;object width="400" height="300"&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=7425032&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1" /&gt;&lt;embed src="http://vimeo.com/moogaloop.swf?clip_id=7425032&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="300"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;The complete code is placed at &lt;a href="http://bitbucket.org/sunneach/render"&gt;BitBucket&lt;/a&gt; to play with.&lt;br /&gt;&lt;br /&gt;The idea: I was scrolling through the Beebole &lt;a href="http://beebole.com/pure/version2/"&gt;examples&lt;/a&gt; (selecting jquery there) and the Example #5, "Dynamic Table", had double rendering in it. It was a bit sad when I noticed the columns were pre-defined in the rendering directive and JSON structure was used only for the record rendering:&lt;br /&gt;&lt;pre&gt;var ex05 = {&lt;br /&gt; template:'table.partialTable',&lt;br /&gt; data:{&lt;br /&gt; cols:['name', 'food', 'legs'],&lt;br /&gt; animals:[&lt;br /&gt; {name:'bird', food:'seed', legs:2},&lt;br /&gt; {name:'cat', food:'mouse, bird', legs:4},&lt;br /&gt; {name:'dog', food:'bone', legs:4},&lt;br /&gt; {name:'mouse', food:'cheese', legs:4}&lt;br /&gt; ]&lt;br /&gt;},&lt;br /&gt; directive1:{&lt;br /&gt; 'th':{&lt;br /&gt;    'col&lt;-cols':{&lt;br /&gt;    '.':'col'&lt;br /&gt;    }&lt;br /&gt;  },&lt;br /&gt; 'td':{&lt;br /&gt; 'col&lt;-cols':{&lt;br /&gt;   '@class':'col'&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}, &lt;br /&gt;directive2:{&lt;br /&gt;  'tbody tr':{&lt;br /&gt;     'animal&lt;-animals':{&lt;br /&gt;        'td.name':'animal.name',&lt;br /&gt;        'td.food':'animal.food',&lt;br /&gt;        'td.legs':'animal.legs'&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;As you can see, the rendered table will always have name, food and legs columns, and there is no control by JSON over it.Well, a little upgrade and it all gets resolved.&lt;pre&gt;var ex05 = {&lt;br /&gt; template:'table.partialTable',&lt;br /&gt; data:{&lt;br /&gt;     cols:['name', 'food', 'legs'],&lt;br /&gt;     animals:[&lt;br /&gt;        {name:'bird', food:'seed', legs:2},&lt;br /&gt;        {name:'cat', food:'mouse, bird', legs:4},&lt;br /&gt;        {name:'dog', food:'bone', legs:4},&lt;br /&gt;        {name:'mouse', food:'cheese', legs:4}&lt;br /&gt;     ]},&lt;br /&gt; directive1:{&lt;br /&gt;    'th':{&lt;br /&gt;          'col&lt;-cols':{&lt;br /&gt;          '.':'col'&lt;br /&gt;          }&lt;br /&gt;     },&lt;br /&gt;    'td':{&lt;br /&gt;       'col&lt;-cols':{&lt;br /&gt;       '@class':'col'&lt;br /&gt;       }&lt;br /&gt;     }&lt;br /&gt; }, &lt;br /&gt; directive2:{&lt;br /&gt;  'tbody tr':{&lt;br /&gt;     'animal&lt;-animals':{ // loop over all records&lt;br /&gt;        'td': { &lt;br /&gt;            'col &lt;- cols': {  // take each column in cols&lt;br /&gt;               '.': recValue, // td value will be a result of call to recValue&lt;br /&gt;               '@class':'col' // optional line - the class of &lt;td&gt; will be the col value from the loop&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;// the standard arg has an item property and all the context: arg.animal.item is current external loop value (records) &lt;br /&gt;function recValue(arg){&lt;br /&gt;   return arg.animal.item[arg.item];&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;What is going on here?The external loop, animal &lt;- animals places into the animal object the records one by one. For each record, the internal loop by col &lt;-cols gets created. The recValue function gets called with the argument arg, being an object which contains information on both loops. The arg.item carries the running col value. The arg.animal.item carries current animal value. So what left is to get the right value of the animal property, using the col value - that is what the recValue does.So, we have the generic HTML and JavaScript code which uses only "cols" and "animals" names, but the stuff inside JSON will determine what the table will display. &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8555815345499886096-3849229589459249228?l=onerlang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onerlang.blogspot.com/feeds/3849229589459249228/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8555815345499886096&amp;postID=3849229589459249228' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8555815345499886096/posts/default/3849229589459249228'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8555815345499886096/posts/default/3849229589459249228'/><link rel='alternate' type='text/html' href='http://onerlang.blogspot.com/2009/11/pure-version-2-and-truly-dynamic-table.html' title='PURE Version 2 and truly dynamic table rendering.'/><author><name>Serge</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8555815345499886096.post-3986130733212416203</id><published>2009-10-13T16:40:00.000-07:00</published><updated>2009-10-14T07:29:38.254-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='riak'/><category scheme='http://www.blogger.com/atom/ns#' term='webmachine'/><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><title type='text'>Riak on my Ubuntu</title><content type='html'>&lt;span style="font-family:arial;font-size:100%;"  &gt;&lt;br /&gt;[EDIT] The situation with &lt;a href="http://bitbucket.org/justin/riak/src/tip/README"&gt;README&lt;/a&gt; being out of sync is already fixed. That was fast! Actually after all fixes in README the only bump on the road is to install a correct Erlang version. After that, clone, make, edit config/riak-demo.erlenv and start go very smoothly. Please disregard all "fighting" an "lying" below. It was actual just for me.[EDIT]&lt;br /&gt;  &lt;br /&gt;I wanted to install and launch &lt;a href="http://riak.basho.com/"&gt;Riak&lt;/a&gt; on my Ubuntu 9.04.&lt;br /&gt;It did not work out first: my conveniently apt-get-installed Erlang 5.6.4 happened to be incompatible with Riak, so I needed the latest Erlang.&lt;br /&gt;&lt;br /&gt;There is also a minor &lt;a href="http://bitbucket.org/justin/riak/src/tip/README"&gt;README&lt;/a&gt; issue, which is easily remediated below. I hope by the time you will read this that one will be fixed. But the routine I found works with current version OK anyway.&lt;br /&gt;&lt;br /&gt;So, the terribly convenient packager &lt;tt&gt;sudo apt-get install erlang&lt;/tt&gt; does not yet install the newer Erlang 5.7.3, so I had to compile the latest otp_src_R13B02-1.tar.gz myself.&lt;br /&gt;&lt;br /&gt;Here is the sequence which led me to success:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;0. sudo apt-get remove erlang&lt;br /&gt;&gt;&gt;  that depends on your installation. In my case I also needed&lt;br /&gt;&gt;&gt;  0.1      sudo apt-get clean&lt;br /&gt;&gt;&gt;  0.2      sudo apt-get remove erlang-base&lt;br /&gt;-------------------------------------------------------------------&lt;br /&gt;1. sudo apt-get install build-essential libncurses5-dev m4&lt;br /&gt;2. sudo apt-get install openssl libssl-dev&lt;br /&gt;3. tar -zxf otp_src_R13B02-1.tar.gz&lt;br /&gt;4. cd otp_src_R13B02-1&lt;br /&gt;5. ./configure&lt;br /&gt;6. make&lt;br /&gt;7. sudo make install&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now if you are lucky, you have the right version of Erlang:&lt;br /&gt;&lt;pre&gt;serge@ubuntu:~$ erl&lt;br /&gt;Erlang R13B02 (erts-5.7.3) [source] [rq:1] [async-threads:0] [hipe] [kernel-poll:false]&lt;br /&gt;&lt;br /&gt;Eshell V5.7.3  (abort with ^G)&lt;br /&gt;1&gt;&lt;/pre&gt;Now we have to fight with Riak documentation, which is out of sync with Riak too. It seems to be the good sign: real hackers never write documentation! (c) some classics...&lt;br /&gt;&lt;hr&gt;[EDIT]&lt;br&gt;Actually, I have to credit this team with a bunch of nice intros and comments: &lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="http://blog.beerriot.com/2009/08/17/riak-demo-stickynotes/"&gt;the demo&lt;/a&gt;, &lt;li&gt;the &lt;a href="http://riak.basho.com/"&gt;big one&lt;/a&gt; of course,&lt;li&gt; the &lt;a href="http://bitbucket.org/justin/riak/src/tip/doc/"&gt;docs&lt;/a&gt; in the distro - my favorite, &lt;br /&gt;&lt;li&gt; the very cool &lt;a href="http://www.vimeo.com/6973519"&gt;movie presentation&lt;/a&gt; from NYC NOSQL '09&lt;br /&gt;&lt;li&gt;For those (including me) who keep thinking what in the wind is going on here - &lt;a href="http://www.akamai.com/dl/technical_publications/ConsistenHashingandRandomTreesDistributedCachingprotocolsforrelievingHotSpotsontheworldwideweb.pdf"&gt;a bit of theory&lt;/a&gt; is a great help.&lt;br /&gt;&lt;/ol&gt;[/EDIT]&lt;hr&gt;&lt;br /&gt;Here it goes. First, we will replace $RIAK with the path-to-riak in the config/riak-demo.erlenv: line 11 in there will look like&lt;br /&gt;&lt;pre&gt;{riak_heart_command, "(cd /home/serge/src/riak; ./start-restart.sh /home/serge/src/riak/config/riak-demo.erlenv)"}.&lt;/pre&gt;&lt;br /&gt;Now we are ready to launch Riak&lt;br /&gt;&lt;pre&gt;./start-fresh.sh config/riak-demo.erlenv&lt;/pre&gt;&lt;br /&gt;Nothing happens. Riak is supposed to work in the backround now.&lt;br /&gt;Is it?&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;serge@ubuntu:~/src/riak$ ./start-fresh.sh config/riak-demo.erlenv&lt;br /&gt;Attempting to connect to 'riakdemo@127.0.0.1' with cookie riak_demo_cookie...&lt;br /&gt;Connected successfully&lt;br /&gt;Looking for pre-existing object at {&lt;&lt;"riak_demo"&gt;&gt;, &lt;&lt;"demo"&gt;&gt;}...&lt;br /&gt;  Pre-existing object found, modifying&lt;br /&gt;Storing object with new value...&lt;br /&gt;  Written successfully&lt;br /&gt;Fetching object at {&lt;&lt;"riak_demo"&gt;&gt;, &lt;&lt;"demo"&gt;&gt;}...&lt;br /&gt;  Fetched successfully&lt;br /&gt;  Object contained correct value&lt;br /&gt;SUCCESS&lt;/pre&gt;"SUCCESS" looks like success! &lt;br /&gt;&lt;br /&gt;Now there is the point where README is [EDIT] no longer! [/EDIT] "lying", so we will do the right thing on our own:&lt;br /&gt;&lt;pre&gt;serge@ubuntu:~/src/riak$ erl -name riaktest@127.0.0.1 -pa ebin -setcookie riak_demo_cookie&lt;br /&gt;Erlang R13B02 (erts-5.7.3) [source] [rq:1] [async-threads:0] [hipe] [kernel-poll:false]&lt;br /&gt;&lt;br /&gt;Eshell V5.7.3  (abort with ^G)&lt;br /&gt;(riaktest@127.0.0.1)1&gt; net_adm:ping('riakdemo@127.0.0.1').&lt;br /&gt;pong&lt;br /&gt;&lt;/pre&gt; &lt;br /&gt;So far so good, the Riak node is found. Let's work with it: &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(riaktest@127.0.0.1)6&gt;  {ok,C}=riak:client_connect('riakdemo@127.0.0.1').&lt;br /&gt;{ok,{riak_client,'riakdemo@127.0.0.1',&lt;br /&gt;                 &lt;&lt;"20091014003214-riaktest@127.0.0.1-riakdemo@127.0.0.1-13736"&gt;&gt;}}&lt;br /&gt;&lt;/pre&gt;Now the README doc is good to go with again:&lt;pre&gt;&lt;br /&gt;(riaktest@127.0.0.1)6&gt; O0 = riak_object:new(&lt;&lt;"groceries"&gt;&gt;, &lt;&lt;"mine"&gt;&gt;, ["bread"]).&lt;br /&gt;{r_object,&lt;&lt;"groceries"&gt;&gt;,&lt;&lt;"mine"&gt;&gt;,&lt;br /&gt;          [{r_content,{dict,0,16,16,8,80,48,&lt;br /&gt;                            {[],[],[],[],[],[],[],[],[],[],[],[],[],[],...},&lt;br /&gt;                            {{[],[],[],[],[],[],[],[],[],[],[],[],...}}},&lt;br /&gt;                      ["bread"]}],&lt;br /&gt;          [],&lt;br /&gt;          {dict,1,16,16,8,80,48,&lt;br /&gt;                {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],...},&lt;br /&gt;                {{[],[],[],[],[],[],[],[],[],[],[],[],[],...}}},&lt;br /&gt;          undefined}&lt;br /&gt;(riaktest@127.0.0.1)7&gt; C:put(O0, 1).&lt;br /&gt;ok&lt;br /&gt;(riaktest@127.0.0.1)8&gt; {ok, O1} = C:get(&lt;&lt;"groceries"&gt;&gt;, &lt;&lt;"mine"&gt;&gt;, 1).&lt;br /&gt;{ok,{r_object,&lt;&lt;"groceries"&gt;&gt;,&lt;&lt;"mine"&gt;&gt;,&lt;br /&gt;              [{r_content,{dict,2,16,16,8,80,48,&lt;br /&gt;                                {[],[],[],[],[],[],[],[],[],[],[],[],...},&lt;br /&gt;                                {{[],[],[],[],[],[],[],[],[],[],...}}},&lt;br /&gt;                          ["bread"]}],&lt;br /&gt;              [{&lt;&lt;"20091014003214-riaktest@127.0.0.1-riakdemo@127.0.0.1-13736"&gt;&gt;,&lt;br /&gt;                {1,63422699573}}],&lt;br /&gt;              {dict,1,16,16,8,80,48,&lt;br /&gt;                    {[],[],[],[],[],[],[],[],[],[],[],[],[],...},&lt;br /&gt;                    {{[],[],[],[],[],[],[],[],[],[],[],...}}},&lt;br /&gt;              undefined}}&lt;br /&gt;(riaktest@127.0.0.1)9&gt; V = riak_object:get_value(O1).&lt;br /&gt;["bread"]&lt;br /&gt;(riaktest@127.0.0.1)10&gt; O2 = riak_object:update_value(O1, ["milk"|V]).&lt;br /&gt;{r_object,&lt;&lt;"groceries"&gt;&gt;,&lt;&lt;"mine"&gt;&gt;,&lt;br /&gt;          [{r_content,{dict,2,16,16,8,80,48,&lt;br /&gt;                            {[],[],[],[],[],[],[],[],[],[],[],[],[],[],...},&lt;br /&gt;                            {{[],[],[],[],[],[],[],[],[],[],[[...]],[],...}}},&lt;br /&gt;                      ["bread"]}],&lt;br /&gt;          [{&lt;&lt;"20091014003214-riaktest@127.0.0.1-riakdemo@127.0.0.1-13736"&gt;&gt;,&lt;br /&gt;            {1,63422699573}}],&lt;br /&gt;          {dict,1,16,16,8,80,48,&lt;br /&gt;                {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],...},&lt;br /&gt;                {{[],[],[],[],[],[],[],[],[],[],[],[],[],...}}},&lt;br /&gt;          ["milk","bread"]}&lt;br /&gt;(riaktest@127.0.0.1)11&gt; C:put(O2, 1).&lt;br /&gt;ok&lt;br /&gt;(riaktest@127.0.0.1)12&gt; C:list_keys(&lt;&lt;"groceries"&gt;&gt;).&lt;br /&gt;{ok,[&lt;&lt;"mine"&gt;&gt;]}&lt;br /&gt;(riaktest@127.0.0.1)13&gt; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now Riak is really ready for experiments.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8555815345499886096-3986130733212416203?l=onerlang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onerlang.blogspot.com/feeds/3986130733212416203/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8555815345499886096&amp;postID=3986130733212416203' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8555815345499886096/posts/default/3986130733212416203'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8555815345499886096/posts/default/3986130733212416203'/><link rel='alternate' type='text/html' href='http://onerlang.blogspot.com/2009/10/fighting-with-riak.html' title='Riak on my Ubuntu'/><author><name>Serge</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8555815345499886096.post-1226365221092837156</id><published>2009-10-06T05:16:00.000-07:00</published><updated>2009-10-08T05:03:28.515-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='restful'/><category scheme='http://www.blogger.com/atom/ns#' term='webmachine'/><category scheme='http://www.blogger.com/atom/ns#' term='rest'/><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='mochiweb'/><category scheme='http://www.blogger.com/atom/ns#' term='webcandy'/><title type='text'>WebCandy RESTs on WebMachine.</title><content type='html'>&lt;span style=";font-family:arial;font-size:100%;"  &gt;The previous &lt;a href="http://onerlang.blogspot.com/2009/09/erlang-stickynotes-under-webmachine.html"&gt;post&lt;/a&gt; was about merge of the StickyNotes app with WebMachine. The &lt;a href="http://www.bitbucket.org/sunneach/webcandy/get/0.1.zip"&gt;release 0.1&lt;/a&gt; was deployed on &lt;a href="http://www.bitbucket.org/sunneach/webcandy/wiki/o_one"&gt;BitBucket&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;That was the "don't touch anything" approach. The solution was elegant, but the data flow mechanisms were all hidden by the POST.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;In the &lt;a href="http://www.bitbucket.org/sunneach/webcandy/wiki/Home"&gt;release 0.2&lt;/a&gt;  the create, update, delete, read operations were made explicit through the HTTP POST, PUT, DELETE and GET which potentially allows the web server to cache the data and reduce the load.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;The home page allows you to check / turn on / turn off / view the WebMachine TRACE without any extra coding. All functionality is already supplied in the admin resource.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;The JQuery was extended for PUT and DELETE in the application.js - some say that the next JQuery release will have it all. Anyway, it was pretty straitforward copy/paste.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;The notes.erl was slightly edited for the read method to put the data structure inline with the other access methods.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;&lt;br /&gt;The &lt;a href="http://www.bitbucket.org/sunneach/webcandy/get/0.2.zip"&gt;release 0.2 code&lt;/a&gt; with pre-compiled binaries is platform-independent and ready to run. You have to install Erlang/OTP first.&lt;br /&gt;After downloading and unpacking the zip, use the start.sh (or start.cmd on Windows) and point your browser to http://127.0.0.1:8000/&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8555815345499886096-1226365221092837156?l=onerlang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onerlang.blogspot.com/feeds/1226365221092837156/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8555815345499886096&amp;postID=1226365221092837156' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8555815345499886096/posts/default/1226365221092837156'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8555815345499886096/posts/default/1226365221092837156'/><link rel='alternate' type='text/html' href='http://onerlang.blogspot.com/2009/10/webcandy-rests-on-webmachine.html' title='WebCandy RESTs on WebMachine.'/><author><name>Serge</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8555815345499886096.post-1282378610944210821</id><published>2009-09-28T08:59:00.000-07:00</published><updated>2009-10-06T05:42:51.955-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='webmachine'/><category scheme='http://www.blogger.com/atom/ns#' term='stickynotes'/><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='mochiweb'/><category scheme='http://www.blogger.com/atom/ns#' term='webcandy'/><title type='text'>Erlang StickyNotes under WebMachine (MochiWeb)</title><content type='html'>&lt;span style=";font-family:arial;font-size:100%;"&gt;&lt;br /&gt;[Edit] The story &lt;a href="http://onerlang.blogspot.com/2009/10/webcandy-rests-on-webmachine.html"&gt;continues with release 0.2&lt;/a&gt;: the application goes RESTful. Plus, you can now turn the webmachine TRACE ON/OFF right from your browser. [/Edit]&lt;br /&gt;&lt;br /&gt;Kevin Smith from &lt;a href="http://weblog.hypotheticalabs.com/"&gt;Hypothetical labs&lt;/a&gt; has recently stressed the value of the &lt;a href="http://bitbucket.org/justin/webmachine/wiki/Home"&gt;WebMachine&lt;/a&gt;. It happened to be not just yet another "cool" stuff, but the &lt;font style="font-weight: bold;"&gt;real&lt;/font&gt; &lt;font style="font-weight: bold;"&gt;thing&lt;/font&gt;.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;Thanks, Kevin!&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;The best way for me to play with and learn it is to use the real working application. That one happened to be the very nice &lt;a href="http://beebole.com/en/blog/erlang/tutorial-web-application-erlang/"&gt;StickyNotes&lt;/a&gt; created by the Hughes Waroquers of BeeBole. Actually, the BeeBole itself has a trailer which looks inspiring and I see where the roots of coolness come from.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://blog.therestfulway.com/2008/10/beebole-erlangweb-tutorial-webmachine.html"&gt;post&lt;/a&gt; by Justin Sheehy shows how to integrate the StickyNotes with the original design of the WebMachine. He took the StickyNotes "as-is" and put them under the Webmachine layer.&lt;br /&gt;&lt;br /&gt;But the snippets given there which  add up to the resource module, do not work with the newest WebMachine releases. They added the wrq module to encapsulate the Request Data manipulation. The calling convention is updated as well.&lt;br /&gt;&lt;br /&gt;So, to make it up and go a bit further, I have created a new repository in &lt;a href="http://bitbucket.org/sunneach/webcandy/wiki/Home"&gt;bitbucket&lt;/a&gt;.&lt;br /&gt;It took the StickyNotes client and DB parts "as is" and on the protocol level (as was suggested by Justin):&lt;br /&gt;&lt;ul&gt;&lt;li&gt;separate static pages and dynamic traffic between different resources&lt;/li&gt;&lt;li&gt;restrict access methods for each resource&lt;/li&gt;&lt;li&gt;send read requests through GET, not POST (coming soon)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;The distribution, when downloaded is ready to launch (use the run.cmd on Windows) . It only needs working Erlang/OTP.&lt;br /&gt;&lt;br /&gt;The home page is now a "pure" AJAX web client, allowing to switch GET/POST.... and Content Type and see the results in detail, very much like Curl (not that powerful, but handy).&lt;br /&gt;I left some debug prints on the server to see how the data reflects in the back-end.&lt;br /&gt;&lt;br /&gt;The (&lt;a href="http://blog.beerriot.com/2009/04/22/simple-webmachine-put/"&gt;PUT&lt;/a&gt;,&lt;a href="http://blog.beerriot.com/2009/04/23/simple-webmachine-authorization/"&gt;Authorization&lt;/a&gt;,&lt;a href="http://blog.beerriot.com/2009/04/24/simple-webmachine-etags/"&gt;ETAGS&lt;/a&gt;,&lt;a href="http://blog.beerriot.com/2009/04/27/simple-webmachine-delete/"&gt;DELETE&lt;/a&gt;) posts of Bryan Fink were extremely helpful to get the concept. Well, POST is not there, but it is &lt;a href="http://bitbucket.org/sunneach/webcandy/src/tip/src/webmstn_notes_resource.erl"&gt;here&lt;/a&gt; now! And last, but not the least is the the very   &lt;a href="http://blog.therestfulway.com/2009/05/video-slideshow-introducing-webmachine.html"&gt;Justin's screencast&lt;/a&gt;, which is was very inspiring for me.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8555815345499886096-1282378610944210821?l=onerlang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onerlang.blogspot.com/feeds/1282378610944210821/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8555815345499886096&amp;postID=1282378610944210821' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8555815345499886096/posts/default/1282378610944210821'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8555815345499886096/posts/default/1282378610944210821'/><link rel='alternate' type='text/html' href='http://onerlang.blogspot.com/2009/09/erlang-stickynotes-under-webmachine.html' title='Erlang StickyNotes under WebMachine (MochiWeb)'/><author><name>Serge</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8555815345499886096.post-665660811363601966</id><published>2009-07-07T12:58:00.000-07:00</published><updated>2009-07-08T10:16:45.128-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='web server'/><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='webrick'/><title type='text'>Minimal web server on Erlang? Like Ruby' webrick?</title><content type='html'>&lt;span style=";font-family:arial;font-size:100%;"&gt;I needed something nice and simple (read: stand-alone with no dependencies) to embed into the app. The good old Joe Armstrong's &lt;a href="http://www.sics.se/~joe/tutorials/robust_server/robust_server.html/"&gt;Pico&lt;/a&gt;, taken right from the &lt;a href="http://www.sics.se/~joe/tutorials/robust_server.tgz"&gt;distro&lt;/a&gt;, happened to work just fine, with one minor patch in the http_driver.erl:&lt;br /&gt;&lt;span style="line-height: 80%;font-size:80;" &gt;&lt;pre&gt;&lt;br /&gt;&lt; isolate_arg([$:,$ |T], L) -&gt; &lt;br /&gt;    {httpd_util:to_lower(reverse(L)), T};&lt;br /&gt;---&lt;br /&gt;&gt; isolate_arg([$:,$ |T], L) -&gt; &lt;br /&gt;    {string:to_lower(reverse(L)), T};     &lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;Plus, working on Windows, I had to convert the launcher script into the&lt;tt&gt;expose_folder.cmd&lt;/tt&gt;:&lt;span style="line-height: 80%;font-size:80;" &gt;&lt;pre&gt;&lt;br /&gt;@echo off&lt;br /&gt;SET PA=c:\src\web_server&lt;br /&gt;SET PORT=4501&lt;br /&gt;SET ERL="C:\Program Files\erl5.7.1\bin\erl.exe"&lt;br /&gt;SET HOSTNAME=hostname&lt;br /&gt;if %1. EQU start. (&lt;br /&gt;   %ERL% -boot start_sasl -sname webserver001 \&lt;br /&gt;     -pa %PA% -heart -detached -s web_server start %port%&lt;br /&gt;) else ( if %1. EQU debug. (&lt;br /&gt;   %ERL% -sname webserver001 &lt;br /&gt;     -pa %PA% -s web_server start %PORT% &lt;br /&gt;) else ( if %1. EQU  stop. (&lt;br /&gt;  %ERL% -noshell -sname webserver_stopper &lt;br /&gt;     -pa %PA% -s web_server stop webserver001@%HOSTNAME%&lt;br /&gt;  echo  "Stopping Webserver" &lt;br /&gt;) else (&lt;br /&gt; echo "Usage:   expose_folder.cmd {start|stop|debug}" )))&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;adjust the paths in this script&lt;li&gt;put this script into the folder, listed in the PATH environment variable&lt;li&gt;Go to folder which you want to web-enable&lt;li&gt;run the &lt;tt&gt;expose_folder.cmd start&lt;/tt&gt;&lt;li&gt;start &lt;a href="http://localhost:4501/readme.txt"&gt;browsing&lt;/a&gt; your folder&lt;li&gt;stop it using: &lt;tt&gt;expose_folder.cmd stop&lt;/tt&gt;&lt;/ol&gt;&lt;br /&gt;No, I don't want to carry the whole &lt;a href="http://cean.process-one.net/doc/"&gt;CEAN&lt;/a&gt; over and yes, &lt;a href="http://code.google.com/p/mochiweb/"&gt;MochiWeb&lt;/a&gt; is &lt;a href="http://beebole.com/en/blog/erlang/tutorial-web-application-erlang/"&gt;very&lt;/a&gt; cool, but is still a bit too large for my purposes.&lt;br /&gt;&lt;br /&gt;Why "they" can store the tiny Ruby file into any folder to make it the web-enabled, and "we" cannot?&lt;br /&gt;&lt;span style="line-height: 80%;font-size:80;" &gt;&lt;pre&gt;&lt;br /&gt;require 'webrick'&lt;br /&gt;include WEBrick&lt;br /&gt;s = HTTPServer.new(:Port =&gt; 9090,&lt;br /&gt;                   :DocumentRoot =&gt; Dir::pwd )&lt;br /&gt;trap("INT"){ s.shutdown }&lt;br /&gt;s.start&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;Yes, I can work it out for myself, but this is the wheel to re-invent. The official  Erlang distro might have it to make the whole Erlang experience much more fun and right away!&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8555815345499886096-665660811363601966?l=onerlang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onerlang.blogspot.com/feeds/665660811363601966/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8555815345499886096&amp;postID=665660811363601966' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8555815345499886096/posts/default/665660811363601966'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8555815345499886096/posts/default/665660811363601966'/><link rel='alternate' type='text/html' href='http://onerlang.blogspot.com/2009/07/minimal-web-server-on-erlang-like-ruby.html' title='Minimal web server on Erlang? Like Ruby&apos; webrick?'/><author><name>Serge</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8555815345499886096.post-7879946215083419886</id><published>2009-07-06T11:02:00.000-07:00</published><updated>2009-07-06T11:47:27.022-07:00</updated><title type='text'>That was easy - Erlang and CouchDB on Ubuntu 9.04</title><content type='html'>&lt;span style=";font-family:arial;font-size:100%;"&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Installed Ubuntu 9.04 from ubuntu.com ISO&lt;br /&gt;&lt;li&gt;Googled "erlang ubuntu"&lt;br /&gt;&lt;li&gt;Figured that it wouldn't hurt to try&lt;br /&gt;&lt;pre&gt;   sudo apt-get install erlang&lt;/pre&gt;&lt;li&gt;Went to grab some coffee&lt;br /&gt;&lt;li&gt;Gave it a try&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;   user@ubuntu:~/src$ erl&lt;br /&gt;   Erlang (BEAM) emulator version 5.6.5 [source] [async-threads:0] [kernel-poll:false]&lt;br /&gt;&lt;br /&gt;   Eshell V5.6.5  (abort with ^G)&lt;br /&gt;   1&gt; q().&lt;br /&gt;   ok&lt;br /&gt;   2&gt; user@ubuntu:~/src$&lt;br /&gt;&lt;/pre&gt;It is not the latest one, but it is still Erlang!&lt;li&gt;How about CouchDB?&lt;br /&gt;&lt;pre&gt;   sudo apt-get install couchdb&lt;/pre&gt;&lt;li&gt;and test it: &lt;tt&gt;http://localhost:5984/&lt;/tt&gt;&lt;li&gt;see the output:&lt;pre&gt;   {"couchdb":"Welcome","version":"0.8.0-incubating"}&lt;/pre&gt;&lt;/ol&gt;That was easy!&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8555815345499886096-7879946215083419886?l=onerlang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onerlang.blogspot.com/feeds/7879946215083419886/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8555815345499886096&amp;postID=7879946215083419886' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8555815345499886096/posts/default/7879946215083419886'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8555815345499886096/posts/default/7879946215083419886'/><link rel='alternate' type='text/html' href='http://onerlang.blogspot.com/2009/07/that-was-easy-erlang-on-ubuntu-904.html' title='That was easy - Erlang and CouchDB on Ubuntu 9.04'/><author><name>Serge</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8555815345499886096.post-2169825485528824991</id><published>2009-06-26T10:07:00.000-07:00</published><updated>2009-06-27T05:25:44.079-07:00</updated><title type='text'>Search engine attempt for the Standard Erlang Documentation</title><content type='html'>&lt;span style=";font-family:arial;font-size:100%;"&gt;The main Erlang documentation site, &lt;tt&gt;erlang.org/doc&lt;/tt&gt; is a set of static pages, which is not that convenient if you need to find a module quickly. &lt;a href="http://onrays.com/erlang/wiki.htm"&gt;Here&lt;/a&gt; I have attempted to break some ice. The heavy-scripted page contains the list of standard Erlang modules encoded. The relevant links appear in from of you as you type the module name. The tiddlywiki JavaScript engine does the job behind the scene.&lt;br /&gt;&lt;br&gt;It works nicely for me, I also have another file for off-line Erlang doc browsing,&lt;br /&gt;which, if placed into the same folder as the Erlang doc root, will work the same way as the online version.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8555815345499886096-2169825485528824991?l=onerlang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onerlang.blogspot.com/feeds/2169825485528824991/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8555815345499886096&amp;postID=2169825485528824991' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8555815345499886096/posts/default/2169825485528824991'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8555815345499886096/posts/default/2169825485528824991'/><link rel='alternate' type='text/html' href='http://onerlang.blogspot.com/2009/06/search-engine-attempt-for-standard.html' title='Search engine attempt for the Standard Erlang Documentation'/><author><name>Serge</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8555815345499886096.post-7366278354081552155</id><published>2009-06-18T13:24:00.001-07:00</published><updated>2009-06-18T13:48:11.793-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='gsub'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='string'/><category scheme='http://www.blogger.com/atom/ns#' term='replace'/><category scheme='http://www.blogger.com/atom/ns#' term='sub'/><title type='text'>String substitution missing in Erlang - for them lazy boys.</title><content type='html'>&lt;span style=";font-family:arial;font-size:100%;"&gt;I keep seeing complaints that there is no such thing as substring replace &lt;pre&gt;string:sub("Hello, there!","there","World") -&gt; "Hello, World!"&lt;/pre&gt; or the global substitution:&lt;pre&gt;gsub("Hell###, W###rld!","###","o") -&gt; "Hello, World!"&lt;/pre&gt;&lt;br /&gt;&lt;/span&gt;Here is the module &lt;tt&gt;strre.erl&lt;/tt&gt;:&lt;pre&gt;&lt;br /&gt;-module(strre).&lt;br /&gt;-author("Serge: onerlang.blogspot.com").&lt;br /&gt;-purpose("string replace functionality").&lt;br /&gt;-export([sub/3,gsub/3,test/0]).&lt;br /&gt;&lt;br /&gt;sub(Str,Old,New) -&gt;&lt;br /&gt;&lt;br /&gt;   Lstr = len(Str),&lt;br /&gt;   Lold = len(Old),&lt;br /&gt;   Pos  = str(Str,Old),&lt;br /&gt;   if &lt;br /&gt;      Pos =:= 0 -&gt; &lt;br /&gt;                   Str;&lt;br /&gt;      true      -&gt;&lt;br /&gt;           LeftPart = left(Str,Pos-1),&lt;br /&gt;           RitePart = right(Str,Lstr-Lold-Pos+1),&lt;br /&gt;           concat(concat(LeftPart,New),RitePart)&lt;br /&gt;   end.&lt;br /&gt;&lt;br /&gt;gsub(Str,Old,New) -&gt;&lt;br /&gt;  Acc = sub(Str,Old,New),&lt;br /&gt;  subst(Acc,Old,New,Str).&lt;br /&gt;&lt;br /&gt;subst(Str,_Old,_New, Str) -&gt; Str;&lt;br /&gt;subst(Acc, Old, New,_Str) -&gt;&lt;br /&gt;         Acc1 = sub(Acc,Old,New),&lt;br /&gt;         subst(Acc1,Old,New,Acc).&lt;br /&gt;&lt;br /&gt;test() -&gt;&lt;br /&gt;   io:format("~p ~p ~p ~p ~p ~p ~p ~n",&lt;br /&gt;     [&lt;br /&gt;      "SELECT * FROM people WHERE first='John' OR last='John'" =:=&lt;br /&gt;  gsub("SELECT * FROM people WHERE first=$1 OR last=$1","$1","'John'"),&lt;br /&gt;      "aBc" =:= sub("abc","b","B"),&lt;br /&gt;      "Abc" =:= sub("abc","a","A"),&lt;br /&gt;      "abC" =:= sub("abc","c","C"),&lt;br /&gt;      "aac" =:= gsub("bbc","b","a"),&lt;br /&gt;      "abc" =:= gsub("abc","d","C"),&lt;br /&gt;      "abc" =:= sub("abc","d","D")]).&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8555815345499886096-7366278354081552155?l=onerlang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onerlang.blogspot.com/feeds/7366278354081552155/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8555815345499886096&amp;postID=7366278354081552155' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8555815345499886096/posts/default/7366278354081552155'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8555815345499886096/posts/default/7366278354081552155'/><link rel='alternate' type='text/html' href='http://onerlang.blogspot.com/2009/06/string-substitution-missing-in-erlang.html' title='String substitution missing in Erlang - for them lazy boys.'/><author><name>Serge</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8555815345499886096.post-5558044052469602143</id><published>2009-06-18T08:58:00.000-07:00</published><updated>2009-06-18T13:23:49.464-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='decode_col'/><category scheme='http://www.blogger.com/atom/ns#' term='pgsql'/><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><title type='text'>What is the string representation for the float?</title><content type='html'>&lt;span style=";font-family:arial;font-size:100%;"  &gt;The Erlang people hold on to the point where the "123456" is for integer 123456 only, not for 123456.0 float! I was using nice and small &lt;a href="http://github.com/noss/pgsql/tree/master"&gt;pgsql&lt;/a&gt; PostgreSQL driver for Erlang and everything worked cool before I had troubles to fetch float datatype values which are rounded to integer.&lt;br /&gt;&lt;br /&gt;As it happens, the &lt;tt&gt;list_to_float("123")&lt;/tt&gt; will produce an error: &lt;span style="line-height: 90%;font-size:90;" &gt;&lt;pre&gt;&lt;br /&gt;     21&gt; erlang:list_to_float("123").&lt;br /&gt;     ** exception error: bad argument&lt;br /&gt;        in function  list_to_float/1&lt;br /&gt;            called as list_to_float("123")&lt;br /&gt;     22&gt; erlang:list_to_float("123.0").&lt;br /&gt;     123.0&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;That feature was &lt;a href="http://www.nabble.com/list_to_float()-td19309221.html"&gt;explicitly confirmed&lt;/a&gt; by Erlang team, so we have to supply the missing ".0" ourselves. I had to patch the &lt;tt&gt;pgsql_util:decode_col&lt;/tt&gt; locally to make it work:&lt;br /&gt;&lt;/span&gt;&lt;span style="line-height: 90%;font-size:90;" &gt;&lt;pre&gt;&lt;br /&gt;decode_col(#desc{format=text, type=Float}, Value)&lt;br /&gt; when Float =:= float4; Float =:= float8 -&gt;&lt;br /&gt;    ListValue = binary_to_list(Value),&lt;br /&gt;    IsFloat   = string:str(ListValue,"."),&lt;br /&gt;    if&lt;br /&gt;       IsFloat &gt; 0 -&gt; FValue = Value;&lt;br /&gt;       true        -&gt; FValue = Value ++ ".0"&lt;br /&gt;    end,&lt;br /&gt;    list_to_float(FValue);&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8555815345499886096-5558044052469602143?l=onerlang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onerlang.blogspot.com/feeds/5558044052469602143/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8555815345499886096&amp;postID=5558044052469602143' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8555815345499886096/posts/default/5558044052469602143'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8555815345499886096/posts/default/5558044052469602143'/><link rel='alternate' type='text/html' href='http://onerlang.blogspot.com/2009/06/what-is-float.html' title='What is the string representation for the float?'/><author><name>Serge</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8555815345499886096.post-3242261923891794755</id><published>2008-11-07T02:11:00.000-08:00</published><updated>2009-09-01T08:01:54.308-07:00</updated><title type='text'>On the "Problem 8.11"</title><content type='html'>&lt;span style=";font-family:arial;font-size:100%;"  &gt;Joe Armstrong suggests to solve the following problem (8.10.1) in his book &lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;a style="font-family: arial;" href="http://www.pragprog.com/titles/jaerlang/programming-erlang"&gt;Programming Erlang&lt;/a&gt;&lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;:&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-size:100%;"&gt;&lt;span style=";font-family:verdana;font-size:85%;"  &gt;"Write a function start(AnAtom, Fun) to register AnAtom as spawn(Fun). &lt;/span&gt;&lt;span style=";font-family:verdana;font-size:85%;"  &gt;Make sure that your program works correctly in the case when &lt;/span&gt;&lt;span style=";font-family:verdana;font-size:85%;"  &gt;two parallel processes simultaneously evaluate start/2. In this case &lt;/span&gt;&lt;span style=";font-family:verdana;font-size:85%;"  &gt;you must guarantee that one of these processes succeeds and the &lt;/span&gt;&lt;span style=";font-family:verdana;font-size:85%;"  &gt;other fails."&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;The &lt;a href="http://www.nabble.com/Programming-Erlang-Exercise-8.11-td12791301.html#a12791301"&gt;solution&lt;/a&gt; proposed by Ladislav Lenart and slightly &lt;a href="http://forums.pragprog.com/forums/27/topics/124"&gt;modified&lt;/a&gt; by Alain O'Dea included try-&gt;catch mechanism attempts to call the &lt;span style="font-family:courier new;"&gt;register(AnAtom, ...)&lt;/span&gt; &lt;span style="font-style: italic;"&gt;concurrently, &lt;/span&gt;inside the &lt;span style="font-family:courier new;"&gt;try&lt;/span&gt; clause. The hope is that the "second" call will fire an exception which is being caught later:&lt;br /&gt;&lt;span style="line-height: 90%;font-size:90;"&gt;&lt;pre&gt;-module (start_register).&lt;br /&gt;-export ([start/2]).&lt;br /&gt;&lt;br /&gt;start(Atom, Fun) -&gt;&lt;br /&gt; Registrant = self(),&lt;br /&gt;    spawn(&lt;br /&gt;       fun() -&gt;&lt;br /&gt;          try &lt;span style="color: rgb(255, 0, 0);"&gt;register(Atom, self())&lt;/span&gt; of&lt;br /&gt;             true -&gt;&lt;br /&gt;                Registrant ! true,&lt;br /&gt;                Fun()&lt;br /&gt;          catch&lt;br /&gt;             error:badarg -&gt;&lt;br /&gt;                Registrant ! false&lt;br /&gt;          end&lt;br /&gt;       end),&lt;br /&gt;    receive&lt;br /&gt;       true  -&gt; true;&lt;br /&gt;       false -&gt; erlang:error(badarg)&lt;br /&gt;  end.&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;Does this work? I tried to use it manually and it did. But I could not simulate all possible situations which could happen when &lt;span style="font-style: italic;"&gt;a lot &lt;/span&gt;of processes will try to bump upon this line. And even if I could, there is no guarantee something else won't happen which was not tested. Well, that is what exception mechanism is for, but...&lt;br /&gt;but why bother? We have the full power of Erlang specifically designed to take care of concurrency problems!&lt;br /&gt;Instead of performing "suspicious" actions I would "eliminate" concurrency here at all, moving it to the Erlang process mailbox. By allowing only &lt;span style="font-style: italic;"&gt;a single dedicated process&lt;/span&gt; to register atoms. It is registered itself as &lt;span style="font-family:courier new;"&gt;registrar &lt;span style="font-family:arial;"&gt;and serves requests to register other funs. Basically, I am using the Erlang's response to concurrency: "GET IN LINE!", meaning that the mechanism of storing messages in the process mailbox is very well tuned: &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="line-height: 90%;font-size:80;"&gt;&lt;pre&gt;-module(prob8101).&lt;br /&gt;-export([start/2,init_registrar/0]).&lt;br /&gt;&lt;br /&gt;init_registrar() -&gt;&lt;br /&gt;   register(registrar,spawn(fun() -&gt; loop() end)).&lt;br /&gt;&lt;br /&gt;   loop() -&gt;&lt;br /&gt;   receive&lt;br /&gt;      {register,Atom,Fun,From} -&gt;&lt;br /&gt;         case whereis(Atom) of&lt;br /&gt;            undefined -&gt;&lt;br /&gt;               register(Atom,spawn(Fun)),&lt;br /&gt;               From!{registered_ok,Atom,self()},&lt;br /&gt;               loop();&lt;br /&gt;            _Otherwise -&gt;&lt;br /&gt;               From!{already_registered,Atom,self()},&lt;br /&gt;               loop()&lt;br /&gt;         end&lt;br /&gt;   end.&lt;br /&gt;&lt;br /&gt;start(AnAtom, Fun) -&gt;&lt;br /&gt;   registrar ! {register, AnAtom, Fun, self()},&lt;br /&gt;   Rid = whereis(registrar),&lt;br /&gt;   receive&lt;br /&gt;     {Result,AnAtom,Rid} -&gt; Result&lt;br /&gt;   end.&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Here we have only one process calling register(...) and we won't have any troubles with concurrent requests for there are none possible.&lt;br /&gt;&lt;p&gt;Here is the sample session:&lt;br /&gt;&lt;span style="line-height: 90%;font-size:90;"&gt;&lt;pre&gt;~/Documents/erlang myacct$ erl&lt;br /&gt;Erlang (BEAM) emulator version 5.5.4 [source] &lt;br /&gt;[async-threads:0] [kernel-poll:false]&lt;br /&gt;&lt;br /&gt;Eshell V5.5.4  (abort with ^G)&lt;br /&gt;1&gt; c(prob8101).&lt;br /&gt;{ok,prob8101}&lt;br /&gt;2&gt; prob8101:init_registrar().&lt;br /&gt;true&lt;br /&gt;3&gt; prob8101:start(bbb,fun() -&gt; &lt;br /&gt;receive {From,A} -&gt; From!{reply,A} end end).&lt;br /&gt;{bbb,'is undefined'}&lt;br /&gt;registered_ok&lt;br /&gt;4&gt; prob8101:start(bbb,fun() -&gt; &lt;br /&gt;receive {From,A} -&gt; From!{reply,A} end end).&lt;br /&gt;{bbb,'is defined',&lt;0.40.0&gt;}&lt;br /&gt;was_registered&lt;br /&gt;5&gt; &lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8555815345499886096-3242261923891794755?l=onerlang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://onerlang.blogspot.com/feeds/3242261923891794755/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8555815345499886096&amp;postID=3242261923891794755' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8555815345499886096/posts/default/3242261923891794755'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8555815345499886096/posts/default/3242261923891794755'/><link rel='alternate' type='text/html' href='http://onerlang.blogspot.com/2008/11/on-problem-811.html' title='On the &quot;Problem 8.11&quot;'/><author><name>Serge</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
