<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>rkh.im</title>
  <id>http://rkh.im</id>
  <updated>Sun, 10 Mar 2019 03:28:01 GMT</updated>
  <author>
    <name>Konstantin Haase</name>
  </author>
  <entry>
    <title>Ruby 2.1</title>
    <link rel="alternate" href="http://rkh.im/ruby-2.1"/>
    <id>/ruby-2.1</id>
    <published>2013-09-24T15:00:00+00:00</published>
    <updated>2013-09-24T15:00:00+00:00</updated>
    <author>
      <name>Konstantin Haase</name>
    </author>
    <content type="html">&lt;p&gt;Yesterday the first preview for Ruby 2.1 was &lt;a href="https://www.ruby-lang.org/en/news/2013/09/23/ruby-2-1-0-preview1-is-released/"&gt;announced&lt;/a&gt;. The release notes gave a first idea of what's new, but didn't go too much into detail. To find out more, you are pretty much left with diving through the Ruby issue tracker. Since I was already aware of most of these changes, I thought I'd write a quick overview post.&lt;/p&gt;

&lt;p&gt;Side note: Obviously Ruby 2.1 includes all the juicy Ruby 2.0 features that I'm not going to repeat in this post.&lt;/p&gt;

&lt;h3&gt;Refinements&lt;/h3&gt;

&lt;p&gt;Refinements were added in Ruby 2.0, but turned out to be highly controversial, so their functionality was reduced and the feature was marked experimental.&lt;/p&gt;

&lt;p&gt;Refinements allowed you to apply certain monkey patches only to a single Ruby file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;module Foo
  refine String do
    def foo
      self + "foo"
    end
  end
end

using Foo
puts "bar".foo
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Outside of the above file, Strings will not respond to the &lt;code&gt;foo&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;In Ruby 2.1, refinements are no longer experimental and can also be applied within a module, without affecting the top level scope of a file.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;module Foo
  refine String do
    def foo
      self + "foo"
    end
  end
end

module Bar
  using Foo
  puts "bar".foo
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Please note that using refinements extensively can lead to very confusing code and that developers behind other Ruby implementations have already indicated they might not implement this feature at all.&lt;/p&gt;

&lt;h3&gt;Decimal Literals&lt;/h3&gt;

&lt;p&gt;You might be aware that floats are far from ideal when doing calculations with fixed decimal points:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;irb(main):001:0&amp;gt; 0.1 * 3
=&amp;gt; 0.30000000000000004
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A lot of Ruby developers fall back to using integers and only fixing it when displaying the result. However, this only works well if you have indeed have fixed decimal points. If not, you have to use rationals. Which isn't too bad, except there was no nice syntax for them (short of changing the return value of &lt;code&gt;Integer#/&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Ruby 2.1 introduces the &lt;code&gt;r&lt;/code&gt; suffix for decimal/rational literals to fix this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;irb(main):001:0&amp;gt; 0.1r
=&amp;gt; (1/10)
irb(main):002:0&amp;gt; 0.1r * 3
=&amp;gt; (3/10)
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Frozen String Literals&lt;/h3&gt;

&lt;p&gt;When you have a string literal in your code, Ruby will create a new string literal every time that line of code is executed. This has to happen, as strings in Ruby are mutable. This is also why symbols are more efficient in many cases. However, symbols are not strings. For instance, if you want to compare some user input to a symbol, you'll either have to convert the symbol to a string or the string to a symbol. This means you either open yourself up to a denial of service attack, as symbols are not garbage collected, or you again end up with an additional string creation.&lt;/p&gt;

&lt;p&gt;Using symbols for string interpolation will also result in a new string creation, same is true when you want to write a symbol to a socket, the list goes on.&lt;/p&gt;

&lt;p&gt;One way to combat this is to store a string in a constant and then use this constant instead:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Foo
  BAR = "bar"

  def bar?(input)
    input == BAR
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, to deal with the issue of mutability, often times you also freeze the string (which prevents changes from Ruby land, but unfortunately does not give you a performance advantage):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Foo
  BAR = "bar".freeze

  def bar?(input)
    input == BAR
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This can get tedious. Fortunately, Ruby 2.1 introduces a syntax doing something equivalent under the hood:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Foo
  def bar?(input)
    input == "bar"f
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will create a frozen string object once and then reuse it whenever the code is executed.&lt;/p&gt;

&lt;p&gt;If your taste is somewhat like mine, you probably think it looks very strange. The reasoning is that it works like the decimal suffix explained above.
Here's a trick I found to make it look more bearable:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Foo
  def bar?(input)
    input == %q{bar}f
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There is &lt;a href="https://bugs.ruby-lang.org/issues/8909"&gt;an open issue&lt;/a&gt; suggesting to add this suffix to arrays and hashes, too.&lt;/p&gt;

&lt;p&gt;Hat tip to &lt;a href="https://charlie.bz/"&gt;Charlie Somerville&lt;/a&gt; for this patch and suggesting a syntax I would have much preferred.&lt;/p&gt;

&lt;h3&gt;Required Keyword Arguments&lt;/h3&gt;

&lt;p&gt;For some reason this wasn't even mentioned in the announcement.&lt;/p&gt;

&lt;p&gt;Ruby 2.0 introduced keyword arguments:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def foo(a: 10)
  puts a
end

foo(a: 20) # 20
foo        # 10
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;However, this way keyword arguments always needed a default value. In Ruby 2.1 you can now have required keyword arguments:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def foo(a:)
  puts a
end

foo(a: 20) # 20
foo        # ArgumentError: missing keyword: a
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Method Definition returns Method Name&lt;/h3&gt;

&lt;p&gt;In previous Ruby versions, defining a method via &lt;code&gt;def&lt;/code&gt; returned &lt;code&gt;nil&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def foo() end # =&amp;gt; nil
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In Ruby 2.1, it now returns the method name as a symbol:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def foo() end # =&amp;gt; :foo
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is useful for meta programming and other neat things. For instance, did you know that the &lt;code&gt;private&lt;/code&gt; method also takes arguments?&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# only foo will be private
class Foo
  def foo
  end

  private :foo

  # bar is not affected
  def bar
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I use this style a lot in &lt;a href="https://github.com/rkh/mustermann"&gt;mustermann&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now that &lt;code&gt;def&lt;/code&gt; returns the name, this can be used to make a single method private:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# only foo and bar will be private
class Foo
  private def foo
  end

  private \
  def bar
  end

  def baz
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I have created &lt;a href="https://bugs.ruby-lang.org/issues/8947"&gt;an issue&lt;/a&gt; to expand this behavior to other ways of defining methods as well.&lt;/p&gt;

&lt;h3&gt;Removing Garbage Bytes from Strings&lt;/h3&gt;

&lt;p&gt;Ruby now comes with a handy method to remove garbage bytes from strings:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;some_string.scrub("")
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This has perviously such a pain to get working across Ruby implementations that I even wrote &lt;a href="https://github.com/rkh/coder"&gt;a library&lt;/a&gt; for this.&lt;/p&gt;

&lt;h3&gt;StringScanner supports Named Captures&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;StringScanner&lt;/code&gt; in the standard library is awesome. In fact, &lt;a href="https://github.com/rails/rails/search?q=strscan&amp;amp;ref=cmdform"&gt;Rails&lt;/a&gt; is using it for parsing route patterns, and so will Sinatra 2.0. Check out Aaron's tutorial on &lt;a href="https://practicingruby.com/articles/parsing-json-the-hard-way?u=90296723ac"&gt;practicingruby.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Ruby 1.9 introduced named captures for regular expressions, however, StringScanner didn't support it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'strscan'
s = StringScanner.new("foo")
s.scan(/(?&amp;lt;bar&amp;gt;.*)/)
puts s[:bar]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;On Ruby 2.0 this will result in:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;TypeError: no implicit conversion of Symbol into Integer
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And on Ruby 2.1:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;foo
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is actually a patch I added (and I used &lt;code&gt;goto&lt;/code&gt;, oh my god).&lt;/p&gt;

&lt;h3&gt;Accessing Network Interfaces&lt;/h3&gt;

&lt;p&gt;You can now access the network interfaces via &lt;code&gt;Socket.getifaddrs&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'socket'

Socket.getifaddrs.each do |i|
  puts "#{i.name}: #{i.addr.ip_address}" if i.addr.ip?
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For me, the above prints:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;lo0: fe80::1%lo0
lo0: 127.0.0.1
lo0: ::1
en0: fe80::1240:f3ff:fe7e:594e%en0
en0: 192.168.178.30
en2: fe80::3e07:54ff:fe6f:147a%en2
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Faster Numbers for Serious Math&lt;/h3&gt;

&lt;p&gt;Ruby 2.1 is now faster when it comes to large numbers, as it uses 128 bit integers for representing bignums internally now if available. They also got an additional speed boost by using the &lt;a href="http://gmplib.org/"&gt;GNU Multiple Precision Arithmetic Library&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;VM changes&lt;/h3&gt;

&lt;p&gt;The underlying virtual machine now doesn't solely rely on a global method cache, instead it also does call site caching. I gave &lt;a href="https://speakerdeck.com/rkh/aloha-ruby-conf-2012-message-in-a-bottle"&gt;a talk about this topic&lt;/a&gt; if you're interested.&lt;/p&gt;

&lt;h3&gt;RGenGC&lt;/h3&gt;

&lt;p&gt;Ruby now has a "partially" generational GC. This will speed up GC, which up until now was a conservative, stop the world, mark and sweep GC.&lt;/p&gt;

&lt;p&gt;It basically still is. For some objects. This is hard to change due to Ruby's internal/external C API.&lt;/p&gt;

&lt;p&gt;However, in Ruby 2.1, the VM will classify objects as sunny or as shady, depending on whether they need to have the normal treatment or not. There are different operations that will turn a sunny object into a shady one. For instance, handing them to a C extension. Other objects, like open files, are classified shady to begin with.&lt;/p&gt;

&lt;p&gt;The sunny objects can be handled by a generational GC. Koichi Sasada gave a talk about this &lt;a href="http://rubykaigi.org/2013/talk/S73"&gt;at RubyKaigi&lt;/a&gt; and &lt;a href="http://www.ustream.tv/recorded/35107339/highlight/377033"&gt;at Euruko&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Updated RubyGems&lt;/h3&gt;

&lt;p&gt;RubyGems has been updated to 2.2.0, which comes with a few &lt;a href="https://github.com/rubygems/rubygems/blob/master/History.txt"&gt;minor enhancements&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Just a Preview&lt;/h3&gt;

&lt;p&gt;Please be aware that yesterdays release is just a preview and all of the above is subject to change.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>The long way to Mexico</title>
    <link rel="alternate" href="http://rkh.im/magmaconf"/>
    <id>/magmaconf</id>
    <published>2013-03-11T10:00:00+00:00</published>
    <updated>2013-03-11T10:00:00+00:00</updated>
    <author>
      <name>Konstantin Haase</name>
    </author>
    <content type="html">&lt;p&gt;&lt;figure class='right first'&gt;&lt;/p&gt;

&lt;blockquote class="twitter-tweet" width="250" data-cards="hidden"&gt;
  &lt;p&gt;
    Both @&lt;a href="https://twitter.com/bmizerany"&gt;bmizerany&lt;/a&gt; and @&lt;a href="https://twitter.com/konstantinhaase"&gt;konstantinhaase&lt;/a&gt; will be at @&lt;a href="https://twitter.com/magmarails"&gt;magmarails&lt;/a&gt; next week. Get your ticket now: &lt;a href="http://t.co/SNm1U725" title="http://magmarails.eventbrite.com/"&gt;magmarails.eventbrite.com&lt;/a&gt;
  &lt;/p&gt;&amp;mdash; Sinatra (@sinatra) &lt;a href="https://twitter.com/sinatra/status/121417262656798720"&gt;October 5, 2011&lt;/a&gt;&lt;/blockquote&gt;


&lt;script async src="//platform.twitter.com/widgets.js" charset="utf-8"&gt;&lt;/script&gt;


&lt;p&gt;&lt;/figure&gt;&lt;/p&gt;

&lt;p&gt;In 2011 I was supposed to &lt;a href="http://2011.magmarails.com/speakers"&gt;speak at MagmaRails&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;At the time, I was working on Rubinius and related projects from Portland, Oregon. The whole thing was sponsored by &lt;a href="https://blog.engineyard.com/2012/my-summer-of-open-source"&gt;Engine Yard&lt;/a&gt;. In case you didn't know, they rock.&lt;/p&gt;

&lt;p&gt;Anyhow, they would have covered my trip to Manzanillo. Would have. But then &lt;a href="http://goo.gl/0WqSL"&gt;Hurricane Jova&lt;/a&gt; decided to cancel the event.&lt;/p&gt;

&lt;p&gt;Three times since have I been invited to Mexico. And so far, I couldn't make it.&lt;/p&gt;

&lt;p&gt;A few things changed since then: First, I'm back in Germany, which is a bit farther away from Mexico than the US is. And second, I no longer have Engine Yard sponsoring me. But I still work on &lt;a href="/sinatra-1.4"&gt;Open Source&lt;/a&gt; full time. Silly me.&lt;/p&gt;

&lt;p&gt;Doing a lot of Open Source means I get invited to &lt;a href="/almost-sinatra"&gt;speak&lt;/a&gt; at a few conferences each year. Since &lt;a href="https://travis-ci.org"&gt;Travis CI&lt;/a&gt; is by far not making enough money (yet) to cover my travel expenses or pay me enough so I can do it myself, I always insist on the conference covering the costs.&lt;/p&gt;

&lt;p&gt;I did the same for the three invitations I've got from MagmaRails, by now called &lt;a href="http://magmaconf.com/"&gt;MagmaConf&lt;/a&gt;. However, it's not easy to find sponsors for a community organized conference in Mexico. Every time I was told that they can't cover my costs, maybe next year.&lt;/p&gt;

&lt;p&gt;But this time we won't declare defeat that easily. Instead, we're trying to crowdfund my plane tickets with the &lt;a href="https://bring-konstantin-to.magmaconf.com/"&gt;&lt;em&gt;Bring Konstantin to MagmaConf&lt;/em&gt;&lt;/a&gt; campaign. You would make the conference organizers, the attendees and of course myself extremely happy by shipping in, even if it's just a little.&lt;/p&gt;

&lt;blockquote cite="https://bring-konstantin-to.magmaconf.com/blog"&gt;
  &lt;p&gt;
    We created this fundraiser because we believe that the Ruby community is awesome and there is a strong chance that we can reach the goal. Plus, Konstantin is pitching in with some pretty nice perks, so it's totally worth the contribution!
  &lt;/p&gt;
  &lt;footer&gt;
    &amp;mdash; MagmaConf
  &lt;/footer&gt;
&lt;/blockquote&gt;


&lt;p&gt;Check out the conference's &lt;a href="https://bring-konstantin-to.magmaconf.com/blog/"&gt;blog post&lt;/a&gt; on why they think I should be speaking there.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>What's new in Sinatra 1.4?</title>
    <link rel="alternate" href="http://rkh.im/sinatra-1.4"/>
    <id>/sinatra-1.4</id>
    <published>2013-03-09T21:10:00+00:00</published>
    <updated>2013-03-09T21:10:00+00:00</updated>
    <author>
      <name>Konstantin Haase</name>
    </author>
    <content type="html">&lt;p&gt;&lt;figure class="small right first"&gt;
  &lt;img src="https://raw.github.com/sinatra/resources/master/logo/come-fly-with-me-500.png" alt="" /&gt;
&lt;/figure&gt;&lt;/p&gt;

&lt;p&gt;I'm about to release Sinatra 1.4.0.&lt;/p&gt;

&lt;p&gt;A few house-keeping jobs are still outstanding, like bringing the website up to speed and running it on a few more apps in production (though we've been running it in production for &lt;a href="https://travis-ci.org"&gt;Travis CI&lt;/a&gt; for quite a while without issues) and then we're good to go.&lt;/p&gt;

&lt;p&gt;If you want to give it a try right now, you can install the prerelease via &lt;code&gt;gem install sinatra --pre&lt;/code&gt;. For more infos, check out &lt;a href="https://github.com/sinatra/sinatra#the-bleeding-edge"&gt;&lt;em&gt;The Bleeding Edge&lt;/em&gt;&lt;/a&gt; from the official Sinatra documentation.&lt;/p&gt;

&lt;p&gt;Sinatra follows &lt;a href="http://semver.org/"&gt;Semantic Versioning&lt;/a&gt;, meaning that this is the first release bringing new features since 1.3.0, released in 2011. Let's take a look at these new features.&lt;/p&gt;

&lt;h3&gt;New HTTP Methods&lt;/h3&gt;

&lt;p&gt;With 1.3.0, we added support for &lt;code&gt;PATCH&lt;/code&gt;. 1.4.0 will include &lt;code&gt;LINK&lt;/code&gt; and &lt;code&gt;UNLINK&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Like &lt;code&gt;PATCH&lt;/code&gt;, they were originally included in &lt;a href="http://tools.ietf.org/html/rfc2068"&gt;RFC 2068&lt;/a&gt; and have now been &lt;a href="http://tools.ietf.org/html/draft-snell-link-method-00"&gt;proposed again&lt;/a&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;link '/resource/:id' do |id|
  resource = Resource.find(id)
  resource.links &amp;lt;&amp;lt; env['X_LINK']
  resource.save

  "link established"
end

unlink '/resource/:id' do |id|
  resource = Resource.find(id)
  resource.links.delete env['X_LINK']
  resource.save

  "link removed"
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;See &lt;a href="http://tools.ietf.org/html/rfc5988"&gt;RFC 5988&lt;/a&gt; for more infos on resource linking.&lt;/p&gt;

&lt;h3&gt;Template Updates&lt;/h3&gt;

&lt;p&gt;This release adds support for &lt;a href="https://github.com/sinatra/sinatra#yajl-templates"&gt;Yajl&lt;/a&gt;, &lt;a href="https://github.com/nesquena/rabl#readme"&gt;Rabl&lt;/a&gt;, &lt;a href="http://blambeau.github.com/wlang/"&gt;Wlang&lt;/a&gt; and &lt;a href="http://learnboost.github.com/stylus/"&gt;Stylus&lt;/a&gt; templates.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;get '/style.css' do
  stylus :style
end

get '/list.json' do
  yajl :list
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Moreover, ERb, Haml, Slim, Liquid and Wlang templates can now be nested using blocks:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;get '/' do
  slim(:outer) { slim :inner }
end

__END__

@@ outer
html
  body
    == yield

@@ inner
p Hello World
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can now configure the default layout on a per engine basis, and passing in &lt;code&gt;nil&lt;/code&gt; as layout is now treated the same as passing in &lt;code&gt;false&lt;/code&gt; rather than using the default layout. Also, we've solved a caching issue when using multiple view directories.&lt;/p&gt;

&lt;h3&gt;Play Nice in Classic Mode&lt;/h3&gt;

&lt;p&gt;Up until this release, using Sinatra in &lt;a href="https://github.com/sinatra/sinatra#modular-vs-classic-style"&gt;classic mode&lt;/a&gt; would add certain private methods to &lt;code&gt;Object&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'sinatra'

["some_object"].instance_eval do
  get '/example' do
    "this works in Sinatra 1.3"
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The above example will now raise a &lt;code&gt;NameError&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is important for objects implementing &lt;code&gt;method_missing&lt;/code&gt; without implementing a corresponding &lt;code&gt;respond_to?&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In 1.4, instead of including &lt;code&gt;Sinatra::Delegator&lt;/code&gt; in &lt;code&gt;Object&lt;/code&gt;, it will only extend the &lt;code&gt;main&lt;/code&gt; object.&lt;/p&gt;

&lt;h3&gt;Better Routes Parsing&lt;/h3&gt;

&lt;p&gt;1.4 has a more robust route parsing. For instance, given the following code:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;get '/:name.?:format?' do |name|
  name
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Running the above with Sinatra 1.3 and requesting &lt;code&gt;/foo.bar&lt;/code&gt; will return &lt;code&gt;foo.bar&lt;/code&gt;, on 1.4 it will now return &lt;code&gt;foo&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Plus signs in the URL (not in query params) will now once again be matched as plus signs, not as spaces.&lt;/p&gt;

&lt;h3&gt;Mime-Type Parameters&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;request&lt;/code&gt; object now exposes Mime-Type parameters when parsing the &lt;code&gt;Accept&lt;/code&gt; header:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;get '/', provides: :jpeg do
  compression = request.preferred_type('image/jpeg').
                  params['compress']
  generate_image(compression)
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The above example will take the &lt;code&gt;compress&lt;/code&gt; parameter into account, including multiple entries with weight:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ curl -H 'Accept: image/jpeg; compress=0.25; q=0.1,
    image/jpeg; compress=0.5; q=0.8' http://localhost:4567
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;New Servers&lt;/h3&gt;

&lt;p&gt;&lt;figure class="small right first"&gt;
  &lt;img src="http://puma.io/images/logos/downloads/standard-logo.png" alt="" /&gt;
&lt;/figure&gt;&lt;/p&gt;

&lt;p&gt;In addition to &lt;a href="http://www.ruby-doc.org/stdlib-2.0/libdoc/webrick/rdoc/WEBrick.html"&gt;WebRick&lt;/a&gt;, &lt;a href="http://code.macournoyer.com/thin/"&gt;Thin&lt;/a&gt; or &lt;a href="http://rubyforge.org/projects/mongrel/"&gt;Mongrel&lt;/a&gt;, Sinatra will now automatically pick up &lt;a href="http://puma.io/"&gt;Puma&lt;/a&gt;, &lt;a href="https://github.com/trinidad/trinidad#readme"&gt;Trinidad&lt;/a&gt;, &lt;a href="https://github.com/MacRuby/ControlTower#readme"&gt;ControlTower&lt;/a&gt; or &lt;a href="https://github.com/postmodern/net-http-server#readme"&gt;Net HTTP Server&lt;/a&gt; when installed. The logic for picking the server has been improved and now depends on the Ruby implementation used.&lt;/p&gt;

&lt;h3&gt;Other Changes&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Exception handling has been improved a lot.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;register&lt;/code&gt; method (for registering extensions) is now also delegated in &lt;em&gt;classic&lt;/em&gt; mode.&lt;/li&gt;
&lt;li&gt;You can now &lt;code&gt;redirect&lt;/code&gt; to &lt;code&gt;URI&lt;/code&gt; and &lt;code&gt;Addressable::URI&lt;/code&gt; instances.&lt;/li&gt;
&lt;li&gt;Generated &lt;code&gt;Content-Disposition&lt;/code&gt; values now include the file name even for &lt;code&gt;inline&lt;/code&gt;, not just &lt;code&gt;attachment&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;You can now pass a &lt;code&gt;status&lt;/code&gt; option to &lt;code&gt;send_file&lt;/code&gt; for setting the status code.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;provides&lt;/code&gt; condition now honors an already set &lt;code&gt;Content-Type&lt;/code&gt; (for instance, in a &lt;code&gt;before filter&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Status, headers and body will be set before running after filters. This is very useful if your after filter is modifying the body.&lt;/li&gt;
&lt;li&gt;When calling &lt;code&gt;new&lt;/code&gt; on your modular application (or &lt;code&gt;Sinatra::Application&lt;/code&gt;), it will now return a wrapper object that exposes a few methods, like &lt;code&gt;settings&lt;/code&gt;, instead of the middleware stack directly.&lt;/li&gt;
&lt;li&gt;Sinatra will now respect the &lt;code&gt;$PORT&lt;/code&gt; environment variable, which is for instance set by &lt;a href="http://www.heroku.com/"&gt;Heroku&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Improved compatibility with Rack 1.5, RDoc 4.0 and RubyGems 2.0.&lt;/li&gt;
&lt;li&gt;By default, Sinatra will now only serve &lt;code&gt;localhost&lt;/code&gt; in development mode. You should not be running your production system in development mode.&lt;/li&gt;
&lt;li&gt;The documentation has been largely improved and converted from RDoc to Markdown.&lt;/li&gt;
&lt;li&gt;The &lt;a href="https://github.com/sinatra/sinatra/blob/master/examples/chat.rb"&gt;chat example&lt;/a&gt; has been fixed to work with the latest jQuery.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;New Configuration Options&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;protection&lt;/code&gt; setting now takes a &lt;code&gt;session&lt;/code&gt; option to explicitly enable/disable session based protection modes. This is useful if you set up a custom session implementation, which Sinatra will otherwise miss.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can now &lt;code&gt;disable :x_cascade&lt;/code&gt; to avoid sending the &lt;code&gt;X-Cascade: pass&lt;/code&gt; header if no route matches.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;What's next?&lt;/h3&gt;

&lt;p&gt;Currently there are three fully maintained branches in the Sinatra repository: master is where the main development is happening, but both 1.2.x and 1.3.x currently receive bug fixes and improvements. With the release of 1.4.0, this will change.&lt;/p&gt;

&lt;p&gt;From that point on, 1.3.x will only receive major bug fixes and security fixes, no more general improvements, unless they can easily be backported from 1.4.&lt;/p&gt;

&lt;p&gt;The 1.2.x branch (which is the branch for Ruby 1.8.6 compatibility) will be discontinued. This includes security fixes. You are very much urged to upgrade if you are still running on Sinatra 1.2.&lt;/p&gt;

&lt;p&gt;Once the first new feature makes it into master, it will move on to 1.5 and I will create a 1.4.x branch. However, there is currently no roadmap whatsoever for a 1.5 release.&lt;/p&gt;

&lt;p&gt;I do have some plans for Sinatra 2.0, though. I have had the urge to rewrite large parts of Sinatra for a while and I have a few prototypes lying around. Goal is to end up with a simpler, more flexible and performant code base. It will fully leverage the new &lt;a href="https://github.com/rack/rack/pull/481"&gt;Rack stream hijacking&lt;/a&gt; or the Rack successor (Rack 2.0, Ponies or whatever it will be called) should we have one by then.&lt;/p&gt;

&lt;p&gt;It will probably be Ruby 2.0 only. Before you freak out: It's still a long way until then, there won't be a release any time soon and even once there is a release, there will be a maintained 1.x branch at least until Sinatra 2.1 has been released.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Almost Sinatra</title>
    <link rel="alternate" href="http://rkh.im/almost-sinatra"/>
    <id>/almost-sinatra</id>
    <published>2013-03-08T08:35:27+00:00</published>
    <updated>2013-03-08T08:35:27+00:00</updated>
    <author>
      <name>Konstantin Haase</name>
    </author>
    <content type="html">&lt;p&gt;A while back I implemented a functional &lt;a href="https://github.com/rkh/almost-sinatra"&gt;Sinatra clone&lt;/a&gt; in six
lines of Ruby code.&lt;/p&gt;

&lt;p&gt;I recently gave a talk about this and other useless but amusing things at a conference in Melbourne
and they've just released the video:&lt;/p&gt;

&lt;iframe src="http://player.vimeo.com/video/61087285" width="550" height="310" frameborder="0"
webkitAllowFullScreen mozallowfullscreen allowFullScreen style="margin-bottom: 1em"&gt;&lt;/iframe&gt;


&lt;p&gt;And here are the slides:&lt;/p&gt;

&lt;script async class="speakerdeck-embed" data-id="fe2a38105f8d013056301231381ff75d"
data-ratio="1.33333333333333" src="//speakerdeck.com/assets/embed.js"&gt;&lt;/script&gt;


&lt;p&gt;I hope you enjoy it as much as I did!&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Reloading Ruby Code</title>
    <link rel="alternate" href="http://rkh.im/code-reloading"/>
    <id>/code-reloading</id>
    <published>2010-08-30T19:06:04+00:00</published>
    <updated>2010-08-30T19:06:04+00:00</updated>
    <author>
      <name>Konstantin Haase</name>
    </author>
    <content type="html">&lt;p&gt;As the core of my &lt;a href="http://www.rubysoc.org"&gt;Ruby Summer Of Code&lt;/a&gt; project, I have partly &lt;a href="http://github.com/rkh/rails"&gt;rewritten&lt;/a&gt; &lt;code&gt;ActiveSupport::Dependencies&lt;/code&gt;. I will give an introduction to common reloading strategies and their implementation and discuss my changes to &lt;code&gt;Dependencies&lt;/code&gt;. Even though this part of ActiveSupport is hidden away and not well known, all Rails developers rely on its proper functioning, as it is responsible for autoloading and reloading Ruby code. It is also responsible for producing error messages like "A copy of Something has been removed from the module tree but is still active!" or "Object is not missing constant Something!". But before focusing on &lt;code&gt;Dependencies&lt;/code&gt;, let's talk about the topic in general.&lt;/p&gt;

&lt;p&gt;In this article I will focus on reloading code, since autoloading code is rather simple: You define a &lt;code&gt;const_missing&lt;/code&gt; hook, which is triggered whenever an undefined constant is used. Map the constant name to a path (with &lt;code&gt;Dependencies&lt;/code&gt;, &lt;code&gt;Foo::BarBlah&lt;/code&gt; will be mapped to &lt;code&gt;foo/bar_blah&lt;/code&gt;) and search for that file inside a list of directories, in that case &lt;code&gt;Dependencies.autoload_paths&lt;/code&gt; and, for files that should be autoloaded but not reloaded, &lt;code&gt;Dependencies.autoload_once_paths&lt;/code&gt;. Some other implementations use Ruby's &lt;code&gt;$LOAD_PATHS&lt;/code&gt;, which has the advantage of simply trying to &lt;code&gt;require 'foo/bar_blah'&lt;/code&gt; instead of having to search for a matching file by hand. That way autoloading constants from gems or other formats (i.e. &lt;code&gt;foo.so&lt;/code&gt; instead of &lt;code&gt;foo.rb&lt;/code&gt;) just works. On the other hand this may easily lead to loading other files than intended and reloading files that should not be reloaded.&lt;/p&gt;

&lt;script src="https://gist.github.com/533770.js?file=simple_autoloader.rb"&gt;&lt;/script&gt;


&lt;p&gt;You might have already noticed that such an autoloading approach is working on two different levels: Constants and files. The artificial mapping from constants to files is present in most Ruby project, but it is not a low-level Ruby feature. Neither is code reloading. However, especially in Rails-land, reloading is assumed to just work. That is impossible by design. But there are a couple of different approaches trying to get you as close as possible. The key design decisions are &lt;em&gt;when&lt;/em&gt; to reload &lt;em&gt;what&lt;/em&gt; code and &lt;em&gt;how&lt;/em&gt; to do that. Of these decisions, when to reload is the easiest one, as it does not bring any implications for the code that is reloaded. The reloader can be triggered on any file changes or on specified points/events in your program flow, or a combination of the two. In a web app, you probably only want to reload code on a new request. What code you should reload heavily depends on how you are reloading code.&lt;/p&gt;

&lt;p&gt;In the following I will mainly focus on reloading &lt;a href="http://rack.rubyforge.org/"&gt;Rack&lt;/a&gt; applications. I will avoid going into how Rack works. I don't think you have to understand every juicy detail, but if you have no clue what Rack does, now would be a good time to check it out. A lot of the strategies and libraries described here should also be usable for other applications. However, if you're level of interest in Ruby and Rails has brought you as far as this blog post, you &lt;em&gt;really&lt;/em&gt; should get to know Rack.&lt;/p&gt;

&lt;h2&gt;Abusing Open Classes&lt;/h2&gt;

&lt;script src="https://gist.github.com/544919.js?file=open_class.rb"&gt;&lt;/script&gt;


&lt;p&gt;The concept of Ruby's &lt;a href="http://rubylearning.com/satishtalim/ruby_open_classes.html"&gt;open classes&lt;/a&gt; is demonstrated in the above example. You might already know this technique, especially either from &lt;a href="http://www.infoq.com/articles/ruby-open-classes-monkeypatching"&gt;monkey-patching&lt;/a&gt; other modules/classes or from using modules as &lt;a href="http://ruby-doc.org/docs/ProgrammingRuby/html/tut_modules.html"&gt;namespaces&lt;/a&gt;. It can also be used for reloading. About anything that can be defined in Ruby, can also be redefined at runtime.&lt;/p&gt;

&lt;p&gt;Imagine you have a Rack application called &lt;code&gt;Foo&lt;/code&gt; in &lt;code&gt;foo.rb&lt;/code&gt;. If you load &lt;code&gt;foo.rb&lt;/code&gt; twice, then the definition of &lt;code&gt;Foo&lt;/code&gt; monkey-patches itself. If one method was changed in-between the first and the second loading of &lt;code&gt;foo.rb&lt;/code&gt;, the second version will override the first. If a method did not change, it will be overridden with an unchanged version, which is about the same as not overriding it. Well, except for the fact that it will invalidate any method caches and revert any inlining which might have occurred thus far. But the method's implementation will remain the same. This is not only extremely simple, but as it turns out also rather fast. If you want to reload &lt;code&gt;foo.rb&lt;/code&gt; on every request you could set up a simple middleware for that:&lt;/p&gt;

&lt;script src="https://gist.github.com/544921.js?file=reload_foo.ru"&gt;&lt;/script&gt;


&lt;p&gt;However, this is not &lt;code&gt;require&lt;/code&gt;-friendly. Even if &lt;code&gt;foo.rb&lt;/code&gt; requires &lt;code&gt;bar.rb&lt;/code&gt;, only &lt;code&gt;foo.rb&lt;/code&gt; will be reloaded. One solution would be to use &lt;code&gt;load&lt;/code&gt; instead of &lt;code&gt;require&lt;/code&gt;. However, we want to keep the reloader as invisible as possible. Moreover, this would make reloading &lt;code&gt;bar&lt;/code&gt; only if it changed impossible, as it will be reloaded whenever &lt;code&gt;foo&lt;/code&gt; is reloaded. One option we could use for now is to remove &lt;code&gt;bar&lt;/code&gt; from &lt;code&gt;$LOADED_FEATURES&lt;/code&gt;. That way &lt;code&gt;require 'bar'&lt;/code&gt; would load it again. But now &lt;code&gt;bar&lt;/code&gt; will not be reloaded unless &lt;code&gt;foo&lt;/code&gt; is reloaded. A better way would be to actively reload &lt;code&gt;bar&lt;/code&gt;. The example below reloads any files that where loaded and have changed. We can use &lt;code&gt;mtime&lt;/code&gt; for checking if I file changed&lt;/p&gt;

&lt;script src="https://gist.github.com/549533.js?file=reload_world.ru"&gt;&lt;/script&gt;


&lt;p&gt;Note however, that this really includes &lt;em&gt;any&lt;/em&gt; files that have been loaded, even if those are in a gem or the standard library. However, those files usually do not change. Still, this approach might not be useful for bigger apps, as there are files you might not want to reload even if they changed (think initializers). In case this approach is exactly what you want, there is a Rack middleware doing exactly this: &lt;a href="http://github.com/rack/rack/blob/master/lib/rack/reloader.rb"&gt;Rack::Reloader&lt;/a&gt;. Not only does it also include error handling and has some nifty features like the ability to set a cool down phase, you probably have it already installed, as it ships with Rack. Combine it with the autoloader code from above and you got Dependencies Lite™.&lt;/p&gt;

&lt;p&gt;For smaller or well written applications this will work perfectly fine, but you will not be able to use it for a Rails or even a Sinatra app. First, instance and class variables don't get invalidated:&lt;/p&gt;

&lt;script src="https://gist.github.com/549586.js?file=old_vars.rb"&gt;&lt;/script&gt;


&lt;p&gt;The body gets reevaluated:&lt;/p&gt;

&lt;script src="https://gist.github.com/549586.js?file=double_alias.rb"&gt;&lt;/script&gt;


&lt;p&gt;Inheritance cannot be changed:&lt;/p&gt;

&lt;script src="https://gist.github.com/549586.js?file=superclass_mismatch.rb"&gt;&lt;/script&gt;


&lt;p&gt;Methods and constants cannot be removed (at least not by removing them):&lt;/p&gt;

&lt;script src="https://gist.github.com/549586.js?file=remove_method.rb"&gt;&lt;/script&gt;


&lt;p&gt;While the last one is usually not a big issue, the other two make it unusable for Rails. Sinatra will keep the old routes and append the modified ones on a reload. To solve this, you can call &lt;code&gt;Sinatra::Application.reset!&lt;/code&gt;. This will only work if you always reload all files. If you want to have partial reloading, try &lt;a href="http://github.com/rkh/sinatra-reloader"&gt;Sinatra::Reloader&lt;/a&gt;. But still, for your own code you should be aware of these issues. A rule of thumb: Using open classes should work just fine if you are willing to manually restart your application in case one of the above issues should occur and if you favor inheritance and mixins over &lt;code&gt;alias_method_chain&lt;/code&gt;, write your files so that executing them twice does not do any harm and you avoid black magic. You probably don't if you are developing a Rails app. You probably do if you are developing a Sinatra or Rack app.&lt;/p&gt;

&lt;h2&gt;Actually restarting your application&lt;/h2&gt;

&lt;p&gt;OK, so apparently relying on open classes is not usable without constrains. One solution that should work without restrictions would be to actually restart the application instead of reloading just some files. Think about it: It's what you would probably do manually if you're application has no reloading baked in. The implementations usually rely on &lt;a href="http://www.kernel.org/doc/man-pages/online/pages/man2/fork.2.html"&gt;fork&lt;/a&gt;. The strategy is simple: Load everything that should not be reloaded, fork and load everything that should be reloaded. Answer requests from that fork. For reloading: Kill the fork, fork away and again, load everything that should be reloaded. The main issue is watching for changes.&lt;/p&gt;

&lt;p&gt;As reloading is triggered from the outside, you have no clue what files are loaded. One strategy would be to again simply reload on every request. &lt;a href="http://github.com/rtomayko/shotgun"&gt;Shotgun&lt;/a&gt; does this. Another option would be to simply watch the current directory for any changes. A general purpose implementation would be &lt;a href="http://github.com/alexch/rerun"&gt;rerun&lt;/a&gt;. Since rerun is intended to be usable with any application, not just Rack apps, it does lack the preloading feature. Therefor reloading probably occurs a lot less than with shotgun, but takes longer.&lt;/p&gt;

&lt;p&gt;My favorite implementation of this strategy is &lt;a href="http://namelessjon.posterous.com/magical-reloading-sparkles"&gt;"Magical Reloading Sparkles"&lt;/a&gt; by Jonathan D. Stott (aka namelessjon). Unicorn has a signal-based redeployment mechanism. Jonathan's code will trigger it on any code change and cause unicorn to kill and refork all workers. In contrast to shotgun it is also easily possible to specify exactly which code should be preloaded.&lt;/p&gt;

&lt;p&gt;So, why not use this approach? As it does a lot more work under the hood (besides reloading more code than the other approaches, it also fires a new system process) and eats more resources, it is generally slower. I would still recommend it for complex applications, if it only reloads on changes or for really small apps that fire up instantly. Under no circumstances would I recommend using shotgun for a Rails app, but for small Sinatra apps it should be acceptably fast. The main issue, however, is portability: Unix forking is not available on Windows nor JRuby, neither is Unicorn. Offering it as default strategy for Rails would limit official support to Unix and MRI. Note that it &lt;a href="http://github.com/rtomayko/shotgun/issues/closed#issue/13/comment/171837"&gt;would probably be possible&lt;/a&gt; to implement something similar for Windows.&lt;/p&gt;

&lt;h2&gt;Replacing Constants&lt;/h2&gt;

&lt;p&gt;We can do something similar to restarting the app: Remove the old constants before reloading. That way, the old code does not survive: No old instance variables or methods lying around, aliasing works as the body will only be reloaded once per constant incarnation, and since the constant will be redefined instead of reopened on every reload, we can even change its superclass:&lt;/p&gt;

&lt;script src="https://gist.github.com/555026.js?file=remove_const.rb"&gt;&lt;/script&gt;


&lt;p&gt;Let's try to use that:&lt;/p&gt;

&lt;script src="https://gist.github.com/555031.js?file=remove_const.ru"&gt;&lt;/script&gt;


&lt;p&gt;The above gist also points to one of the main issues of this approach: Invalidating references. When using open classes, &lt;code&gt;Foo&lt;/code&gt; always referenced the same object, it just evolved. Now &lt;code&gt;Foo&lt;/code&gt; is a different object before and after each reload.&lt;/p&gt;

&lt;p&gt;If you pass &lt;code&gt;Foo&lt;/code&gt; to &lt;code&gt;run&lt;/code&gt;, &lt;code&gt;Rack::Builder&lt;/code&gt; will use the object passed, which would remain unchanged on the next reload. By wrapping it a new constant lookup will be triggered on every request and thus changes will be picked up. It gets even worse as soon as you realize that the same goes for instances:&lt;/p&gt;

&lt;script src="https://gist.github.com/555145.js?file=surviving_instances.rb"&gt;&lt;/script&gt;


&lt;p&gt;This cannot be fixed entirely. However, it is possible to alleviate these problems.&lt;/p&gt;

&lt;h2&gt;The Rails Way&lt;/h2&gt;

&lt;p&gt;Imagine you where able to remove everything and load all from scratch. That way no old references would survive and no constants could be kept alive. In a nutshell, this is what Rails is trying to do, except, not really. As mentioned above, reloading everything might not be what you want. You might lose state or you even might execute files twice that should not be run twice otherwise. Therefore ActiveSupports divides all constants into two groups: The part that should be reloaded and the part that should not be reloaded. As a rule of thumb the reloadable constants are your app code (models, controllers, extra, etc) and the rest is kept (lib, initializers, external dependencies, etc).&lt;/p&gt;

&lt;p&gt;Everything works fine if you only reference reloadable constants from other reloadable constants (at least if the references would otherwise survive to the next request and would be reused). In order to achieve this, it might be necessary to add constants explicitly to the reloadable pool. This is possible by calling &lt;code&gt;Module#unloadable&lt;/code&gt; on the constant. Note however that marking a constant as reloadable will essentially cause the constants' source file to be reloadable, so if it has any side-effects besides defining the constants, those will reoccur on any request.&lt;/p&gt;

&lt;p&gt;The hard thing is to track which constants belong to what pool. ActiveSupport creates a watch stack for that. It tracks which constants are already known and is able to return a list of new constants for a block of code. It then hooks this mechanism into the autoloading code, require and load. Autoloaded constants will automatically be added to the reloadable pool. However, if the file defining the constant requires other files, ActiveSupport has to be careful to only add the autoloaded constant to the pool, not necessarily its dependencies. Another threat is accidentally loading a file twice before removing its constant, as in that case you would have the issues of the open class approach you were trying to get rid off. ActiveSupport therefore juggles with multiple lists besides the watch stack to track all files that have ever been autoloaded, all files that have been loaded since the last reload ("ActiveSupport::Dependencies.clear", btw), all automatically loaded constants since the last reload and all constants explicitly marked for reload. Also, combinations of those lists are used extensively.&lt;/p&gt;

&lt;p&gt;ActiveSupport removes all reloadable constants after each request and relies on the autoloading hook to reload any required constants. That way on reach request only the constants needed to serve the page should be loaded. In production mode, constants will simply not be removed and autoloading will happen in an eager manner (before the app starts serving), since autoloading is not thread-safe. If loading a file defining a constant raises an error, ActiveSupport also takes care of removing that constant again, thus avoiding "broken" constants.&lt;/p&gt;

&lt;h2&gt;The Rails Way, reloaded&lt;/h2&gt;

&lt;p&gt;ActiveSupport 3.0, even though a lot less than 2.3.5 did, either blows up in your face or does not even mind if anything went wrong. This was the initial motivation for my project proposal. My goal was to reduce error messages. In order to do that, I changed the inner architecture of &lt;code&gt;ActiveSupport::Dependencies&lt;/code&gt; away from a procedural, list juggling to an object oriented approach where every constant has a wrapper knowing whether it is already activated, it is reloadable, and how and when to reload it. At the end of each request still all constants are removed, but the wrappers are kept. Now, the wrapper can decide whether to restore the wrapped constant or to reload it from source.&lt;/p&gt;

&lt;p&gt;In order to do so the developer can choose a reloading strategy. This is probably only relevant for plugin or middleware developers (due to extensive reference keeping, the constant removing approach is rather annoying when writing Rack middleware). The default strategy is the world reloader. The world reload will all cause all constants to be reloaded if a single file referencing a constant with this strategy was changed. This is essentially the same as the current Rails strategy plus checking for changes. ActiveSupport can also pretend a change occurred on every request and skip the &lt;code&gt;mtime&lt;/code&gt; checking. This is an advantage if you have a setup where loading files is rather cheap and checking &lt;code&gt;mtimes&lt;/code&gt; is expensive. Another strategy best set on per constant level, is the open class strategy. It is activated via &lt;code&gt;unloadable :monkey_patching&lt;/code&gt;. If you do so, changing that file will only reload the constant defined in it and restore the constant before reloading it, thus using the open class and keeping all references to that class intact. A third strategy, that is rather experimental, tries to divide the reloadable pool into smaller sub-pools, reloading only the pools affected by file changes. As Yehuda Katz pointed out, this almost always works in demo scenarios but probably fails when tried for real world cases. It is of course also possible to change the default strategy. Such sub-pools are created by associations, &lt;code&gt;require&lt;/code&gt;, &lt;code&gt;require_dependency&lt;/code&gt; and explicitly by &lt;code&gt;Module#associate_with&lt;/code&gt;. I therefore named it sloppy reloading. Since every strategy is just a mixin, plugin developers doing a lot of rails core work, or developers of other frameworks using ActiveSupport (think Padrino) could easily apply their own strategy (&lt;code&gt;unloadable MyLib::MyStrategy&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;But how does this help with reducing errors? The wrapper approach allows easier tracking of what is happening to a constant. The wrapper has hooks to whenever a constant is added or updated, which reduces the likelihood of a "is already activated" or "is not missing constant" error. Moreover, it shifts errors from the autoloading point to the moment old references are actually used. A old reference no one is touching anymore does no harm. My branch therefore modifies the old constant to be a proxy for the new one as soon as it is replaced by another version. In most cases this will not cause an error but redirect the methods and result in the behavior expected if you would not be aware of the reloading that's going on under the hood. This even works when including modules, as Ruby relies on &lt;code&gt;append_features&lt;/code&gt;, which will also be delegated to the new constant.&lt;/p&gt;

&lt;p&gt;Another issue dealt with is using require on reloadable files. Usually, developers are told to simply avoid &lt;code&gt;require&lt;/code&gt; and use &lt;code&gt;require_dependency&lt;/code&gt; instead. If you require a file containing an explicitly reloadable constant without referencing that constant, it will only be loaded the first time. At that point Ruby adds the file to &lt;code&gt;$LOADED_FEATURES&lt;/code&gt; and will not load it again on a require. After the request finished, ActiveSupport will remove the constant. On a reload you might expect require to load the file or the constant to be defined and then try to access the constant implicitly. In that case you will not be able to reach the constant. The patched version of ActiveSupport therefore takes care of removing files from the &lt;code&gt;$LOADED_FEATURES&lt;/code&gt; if the constant is removed. Tracking such events based on the list architecture would have been a nightmare.&lt;/p&gt;

&lt;p&gt;One last, technically minor issue, is offering an alias for &lt;code&gt;unloadable&lt;/code&gt;. A lot of developers I know initially seem rather confused by &lt;code&gt;unloadable&lt;/code&gt;, sometimes even assuming it does the exact opposite (as the constant it "not loadable"). I therefore added an alias I rather prefer: &lt;code&gt;reloadable&lt;/code&gt;, especially when used with a strategy: &lt;code&gt;reloadable :sloppy&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;Numbers, please&lt;/h2&gt;

&lt;p&gt;Lies, damned lies, and statistics, so here we go. In a simple Sinatra application, I get the following numbers:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; &lt;/th&gt;
      &lt;th&gt;no changes&lt;/th&gt;
      &lt;th&gt;file changed&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;th&gt;No Reloader&lt;/th&gt;
      &lt;td&gt;0.0044671058654&lt;/td&gt;
      &lt;td&gt;-&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;Rack::Reloader&lt;/th&gt;
      &lt;td&gt;0.0231933116912&lt;/td&gt;
      &lt;td&gt;0.0236261129379&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;Sinatra::Reloader&lt;/th&gt;
      &lt;td&gt;0.0088394482930&lt;/td&gt;
      &lt;td&gt;0.0090538899103&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;ActiveSupport&lt;/th&gt;
      &lt;td&gt;0.0207427183787&lt;/td&gt;
      &lt;td&gt;0.0207780686060&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;ActiveSupport Reloaded&lt;/th&gt;
      &lt;td&gt;0.0147878090540&lt;/td&gt;
      &lt;td&gt;0.0208899911244&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;Shotgun&lt;/th&gt;
      &lt;td&gt;0.9925425291061&lt;/td&gt;
      &lt;td&gt;1.0038710657755&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;Magical Reloading Sparkles&lt;/th&gt;
      &lt;td&gt;0.0044739915830&lt;/td&gt;
      &lt;td&gt;0.9384773521974&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;


&lt;p&gt;In a simple Rails 3.0 app serving a page took 0.00793675 seconds, while with my RSoC branch it took 0.00379425 seconds.
Note that you might want to disable &lt;code&gt;mtime&lt;/code&gt; checking on JRuby, as it is about 10 times slower than on MRI and 5 times slower than on Rubinius. If it is worth checking the &lt;code&gt;mtime&lt;/code&gt; on JRuby really depends on how long your files take to load. If you do a lot of instance variable caching and such you might still prefer checking for changes.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Strengths and Weaknesses of Seaside</title>
    <link rel="alternate" href="http://rkh.im/seaside"/>
    <id>/seaside</id>
    <published>2010-08-25T19:14:00+00:00</published>
    <updated>2010-08-25T19:14:00+00:00</updated>
    <author>
      <name>Konstantin Haase</name>
    </author>
    <content type="html">&lt;p&gt;&lt;em&gt;This is an excerpt from my bachelor thesis.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;Core principles&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://seaside.st/"&gt;Seaside&lt;/a&gt;'s approach to web development differs from most other web
frameworks, such as Django or Ruby On Rails, by explicitly breaking
with common patterns and principals the web is built upon, such as
being stateless, having meaningful, maybe even restful URLs or using
template systems.&lt;/p&gt;

&lt;p&gt;When doing web development you often have to work with the construct of a session, that
allows one to keep state in between requests made from the same
browser session. Usually the session is serialized and stored in a
cookie or a database. Seaside takes advantage of Smalltalk's image
based nature by simply keeping the session as an object in the
currently active process.&lt;/p&gt;

&lt;p&gt;This eliminates the overhead of serializing
every object in the session and the need to keep the number of objects
kept by the session small. Seaside goes even further by storing
closures and continuations in the session.&lt;/p&gt;

&lt;p&gt;While most other frameworks use the session as little as possible, in
Seaside it is used for nearly everything. It solely depends on the
state of your session what page is displayed. Usually every Seaside
application features a single entrance point, a so called root
component.&lt;/p&gt;

&lt;p&gt;User navigation is realized by storing continuations and
callbacks (closures) for the currently displayed page. User
interaction will then trigger any associated callbacks, thereby
changing the session's state, and then re-render the possibly changed
content.&lt;/p&gt;

&lt;h2&gt;Advantages over other web frameworks&lt;/h2&gt;

&lt;p&gt;This gives some advantages over classic web development. Applications,
though written for the web, are developed in a way rather similar to
desktop applications. Interactive websites, also known as Rich
Internet Applications, can rapidly be developed.&lt;/p&gt;

&lt;p&gt;In the prototyping phase or when developing small sites, using the
image for storing data eliminates any need for implementing a
persistence layer, like an object-database-mapping mechanism.&lt;/p&gt;

&lt;p&gt;Working on such a high abstraction level compared to normal web
development encourages the developer to use object orientation and
decoupling on other levels than when working with other web
frameworks. Rather than thinking of constructs and working with object
representing requests, streams, cookies or URLs, websites are defined
by components, callbacks and canvases. This can also encourage a
creativity, since it requires developers to think outside of their
common patterns.&lt;/p&gt;

&lt;h2&gt;Downsides of developing with Seaside&lt;/h2&gt;

&lt;p&gt;There are some downsides one has to be aware of when choosing
Seaside. Due to the session based nature and the close coupling of
"rendering", it is rather
complicated to implement public APIs. In many cases Smalltalk
developers fall back to other libraries and protocols to accomplish
this.&lt;/p&gt;

&lt;p&gt;When developing software with Seaside, the commonly
used path is to write in Smalltalk whatever can be written in
Smalltalk. This is especially true as Seaside is able to generade some
JavaScript from Smalltalk, and tools like Glorp do the same for
SQL. This is rather cosy for the developer, who probably favors
Smalltalk over the other languages anyway.&lt;/p&gt;

&lt;p&gt;However, this poses the threat of doing computation in the Seaside
image, that could usually be done in the web browser or at database
level. Moreover, as this results in changes to the HTML output more
often than would be necessary when filling in content via JavaScript,
this also conflicts with established caching techniques. The latter is
not much of  an issue, since HTTP level caching is not feasible with
Seaside, as will be discussed in a moment.&lt;/p&gt;

&lt;p&gt;Seaside applications usually also conflict with established usage
patterns. Tabbed browsing is imposible, so is storing bookmarks for
any page besides the entrance page. If a user shares a link with
another user, not only might that link not work when the current
session expires. This usually happens 10 minutes after the
last HTTP request.&lt;/p&gt;

&lt;p&gt;If the session is not yet expired, the other
user opening the link will end up in the same session as the one
sharing the link with him or her. This will not only lead to
unexpected behavior, but represents a major security risk.&lt;/p&gt;

&lt;h2&gt;Seaside and scalability - deployment issues to be aware of&lt;/h2&gt;

&lt;p&gt;There are also implications on the infrastructure level, especially
when using reverse proxies. At the server side two types of proxies are commonly
used: caches and load balancers.&lt;/p&gt;

&lt;p&gt;HTTP caches are simply not
feasible with Seaside. Techniques like the ETag, Last-Modified
and Cache-Control HTTP headers are unusable, since they rely on
the same content being available under the same URI for multiple
requests. Only application layer caching is an option, but it lacks
general Seaside solutions and does not keep requests from reaching the
image in the first place.&lt;/p&gt;

&lt;p&gt;Although it would be possible to cache a response, the same HTTP
request is extremely unlikely to reoccur and the cache would only
allocate additional system resources, increasing deployment costs
even more.&lt;/p&gt;

&lt;p&gt;Load balancers are rather important when scaling web
applications. When running a web application you usually do not want
to start an application process for every incoming request. Therefore,
in a simple setup, one process, an application server, is started and
all incoming requests are handled by this process.&lt;/p&gt;

&lt;p&gt;The Seaside equivalent is starting a Smalltalk image with Seaside. However,
increasing load might have a major performance impact on the
image. Therefore you often want to launch multiple images on the same
computer or even multiple computers each running at least one instance
of your application and distribute load equally among them.&lt;/p&gt;

&lt;p&gt;This is where the load balancer comes in. The load balancer listens for any
incoming requests and forwards them as equally distributed as possible
to the different images. To reduce overhead the load balancer has to
be as fast as possible. Larger setups therefore use hardware load
balancers working on ethernet level.&lt;/p&gt;

&lt;p&gt;For distribution, the proxy often
relies on round robin, and URI based sharding, as these algorithmes
are simple, efficient and can be implemented at a very low level. As
for the same reasons tabs and bookmarks are not usable, you cannot
rely on URI based sharding.&lt;/p&gt;

&lt;p&gt;Load balancing is a major concern when deploying Seaside
applications, since most Smalltalk implementations rely on green threads
and most Seaside application are not thread-safe. A small number of
users accessing the application simultaneously will already result in
a noticeable increase of response time.&lt;/p&gt;

&lt;p&gt;When having identical application servers, round robin is the simples
way one can imagine to distribute load among them: The first request
is forwarded to the first application server, the second to the
second, and so on. Until you reach the last app server and start with
the first server again. Without additional tools, this approach is not
usable with Seaside, as requests from a single browser session always
have to be forwarded to the same application server.&lt;/p&gt;

&lt;p&gt;The common approach to address this issue is to use an object database, in
most cases the proprietary Gemstone/S system, to persist the current
session and thus share it over the network among all application
servers. While this works remarkably well, it comes with the large
overhead of synchronizing the session and all referenced objects
(including the closures and continuations) for each and every
request.&lt;/p&gt;

&lt;p&gt;Advanced load balancers do not strictly rely on round robin, but track how
many outstanding requests the individual application servers have or
how low their response time is, and distribute incoming requests
accordingly.&lt;/p&gt;

&lt;p&gt;An alternative approach is to always forward requests from the same
client to the same application server. While this approach works even
without sharing sessions among images, it needs additional overhead
and does not distribute load as equally as round robin or any similar
approach.&lt;/p&gt;

&lt;p&gt;Imagine one user would be all a single image could
handle. In that case all users would have to be equally active to
distribute load perfectly among the servers. Moreover, if you have
six users on five application servers, the load balancer would have to
forward two users to the same server.&lt;/p&gt;

&lt;p&gt;To solve the performance issues of those two users, a system
administrator could decide to start yet another application server and
hook it into the load balancer. However, unless a new user appears,
that application server will never be used, as users are always
forwarded to the same application servers. If one application server
crashes, the load balancer will no longer be able to serve to users
previously using that server.&lt;/p&gt;

&lt;p&gt;In a real world example you would therefore configure the load
balancer to only forward to the same image in the most cases, with the
ability of switching images. Unless you are willing to risk losing the
session, that would mean sharing sessions again, but lower the
synchronization overhead.&lt;/p&gt;

&lt;p&gt;By design, this overhead would still be larger than for any web
framework embracing web patterns like REST, and makes scaling Seaside
a hard task to accomplish.&lt;/p&gt;

&lt;h2&gt;Why Seaside?&lt;/h2&gt;

&lt;p&gt;Despite the scalability issues just discussed, we decided to use
Seaside. As a powerful web framework it allowed us to easily implement
the infrastructure described earlier.&lt;/p&gt;

&lt;p&gt;Another important factor was that we should favor
technologies our external partners were using themselves. This largely
influenced our decision towards
&lt;a href="http://www.cincomsmalltalk.com/main/products/visualworks/"&gt;VisualWorks&lt;/a&gt;
and &lt;a href="http://www.glorp.org/"&gt;Glorp&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The only remaining competitor in for this setup would have been the
&lt;a href="http://www.iliadproject.org/"&gt;Iliad&lt;/a&gt; web framework, which is commonly
used with &lt;a href="http://smalltalk.gnu.org/"&gt;Gnu Smalltalk&lt;/a&gt; rather
than VisualWorks. We therefore assumed better support for
Seaside. Moreover, our customer was also developing applications with
Seaside, which made it a perfect candidate for the project.&lt;/p&gt;

&lt;p&gt;Fortunately, scalability was not a concern, as the system will
probably only have one or two users accessing it simultaneously.&lt;/p&gt;
</content>
  </entry>
</feed>
