Dojo4 Blog | All Posts

Writing Hygienic Mixins In Ruby

=begin

  it's quite common, in ruby, for modules to provide functionality via mixins.


  for example:


=end

  module Mixin
    def foo
      42
    end
  end

  class C
    include Mixin
  end

  p C.new.foo #=> 42

=begin

  althouge handy, the guts of the mixin, especially modules, can easily leak
  into the target unintentially.

  here the 'Util' module gets zippered in-between the Mixin and C:


=end

  reset!

  module Mixin
    module Util
      def Util.foo
        42
      end
    end
  end

  class C
    include Mixin

    p Util.foo #=> 42

    module Util
      def Util.bar
        42.0
      end
    end

    p Util.bar #=> 42.0
  end



=begin

  this creates a challenge for the author's of mixins: how to keep code
  organized *and* provide a module that is safe to mixin to any target.


  two main approaches exist:


  1) carve out the mixin seperately from the top-level namespace

=end

  reset!

  module M
    module Mixin
      def foo
        42
      end
    end

    module Util
    end
  end

  class C
    include M::Mixin
  end

  p C.new.foo #=> 42
  p C.const_defined?(:Util) #=> false


=begin

  or

  2) leverage const_missing to allow simple const aliases into a private namespace


=end

  reset!

  module M
    module Namespace
      module Util
        def foo
          42
        end
      end
    end

    def Mixin.const_missing(const)
      begin
        Namespace.const_get(const)
      rescue Object
        raise
      end
    end

    def foo
      Util.foo
    end
  end

  class C
    include M::Mixin
  end

  p C.new.foo #=> 42
  p C.const_defined?(:Util) #=> false 



=begin


  so, there you have it: please think carefully about dropping common names
  inside your mixins as they absolute vommit all their internals into the
  mixee.


=end









BEGIN {
  def reset!
    self.class.send :remove_const, :Mixin rescue false
    self.class.send :remove_const, :C rescue false
  end
}

Mobile Detection behind a CDN

In a recent project, we were tasked with building the mobile version of an existing website. The existing website really wasn't a good candidate for a responsive design, so we decided to create a completely new version of the site for mobile devices.

5547851770_3598506559_z.jpg (photo by Johan Larsson)

At first we were thinking of using the m.example.com pattern, where the sites are entirely separate domains. However since we don't manage the infrastructure for this site, we wanted to go with an approach that would require as few infrastructure changes as possible. Supporting another domain on the same servers isn't very difficult, but it's just another task that's easy to mess up and not necessary in our case.

Empathy in (F)OSS

I recently came across a tweet that was really surprising to me. To provide some context, the tweet was authored by someone that maintains a popular javascript library on GitHub. It has since been deleted, but here is the text:

Most people are garbage. Some are amazing. Count yourself super lucky if you're friends with some of the amazing ones.

Goodness. Gracious. I wonder if that statement includes all of the people that take the time to learn and use their software? Giving them the benefit of the doubt though, I'm hoping that it was just a product of a bad day. I ended up spinning on something that I think is important: Among many other things, you have to be empathetic to be a great open source contributor or maintainer.