URI: 
       HERE'S HOW YOU CAN USE SWITCH CASES IN LUA
       
   IMG iillustration-9.png
       
       Kidding! You can't! Lua doesn't have a `switch' operator. Instead, it
       has tables. And tables are actually much more interesting, and far
       easier to work into a routine that requires evaluating statements
       based on conditions. Don't believe me? Here's an example of how I've
       put tables to use.
       
       The context: I'm building a RSS reader for KOReader. Sometimes the RSS
       reader needs to fetch a web page, which it then parses, deconstructs,
       and re-builds as an EPUB. To re-build the web page into an EPUB, I
       create objects for each of the website's components, like the HTML
       document and any images it contains. I call these "items". Different
       types of items have different private methods, but they all share the
       same two data points: `path' and `content'. Because all items share
       these two data points, I've decided to make a common interface for
       their construction: `ItemFactory'.  Supplying the `makeItem' method
       within `ItemFactory' with the item's `path' and `content' will
       "automatically" construct the item with the appropriate constructor.
       
       How? First: a file extension is derived from the item's `path.' This
       value is matched against the `ITEM_TYPES' table. The keys of this
       table represent the supported item types. The values for each key
       represent the item type's supported file formats (given as
       extensions). When a match is found, the table key is stored in a
       variable. Next, (and this is the exciting part) that variable's value
       is used as an index into the `ITEM_CONSTRUCTORS' table, which contains
       constructors for each supported item type. The indexed constructor is
       returned and then supplied with the `path' and `content' data that was
       passed to the factory.
       
       Cool, right? What I love so much about this no-switch switch-like
       logic is that the `makeItem' method basically reads like a unit
       test. It stays focused on returning errors when conditions aren't
       met. The actually divining of what code gets evaluated, and what that
       code does/looks like gets tucked away into a table. Extending the code
       is simple, maintaining the code is clear. It's bliss!
       
       ,----
       |   local ItemFactory = {
       | 
       |   }
       | 
       |   ItemFactory.ITEM_TYPES = {
       |      xhtml = XHtmlItem.SUPPORTED_FORMATS,
       |      image = Image.SUPPORTED_FORMATS
       |   }
       | 
       |   ItemFactory.ITEM_CONSTRUCTORS = {
       |      xhtml = function(path, content)
       |         return XHtmlItem:new{
       |            path = path,
       |            content = content,
       |         }
       |      end,
       |      image = function(path, content)
       |         return Image:new{
       |            path = path,
       |            content = content
       |         }
       |      end
       |   }
       | 
       |   function ItemFactory:makeItem(path, content)
       |      local suffix = util.getFileNameSuffix(
       |         string.lower(path)
       |      )
       | 
       |      local matched_type = ItemFactory:getItemTypeFromFileNameSuffix(suffix)
       |      if not matched_type
       |      then
       |         return false, EpubError.ITEMFACTORY_UNSUPPORTED_TYPE
       |      end
       | 
       |      local item_constructor = ItemFactory.ITEM_CONSTRUCTORS[matched_type]
       |      if not item_constructor
       |      then
       |         return false, EpubError.ITEMFACTORY_NONEXISTENT_CONSTRUCTOR
       |      end
       | 
       |      return item_constructor(path, content)
       |   end
       | 
       |   function ItemFactory:getItemTypeFromFileNameSuffix(suffix)
       |      local matched_item_type = nil
       |      for item_type, supported_formats in pairs(ItemFactory.ITEM_TYPES) do
       |         if supported_formats[suffix]
       |         then
       |            matched_item_type = item_type
       |            break
       |         end
       |      end
       |      return matched_item_type
       |   end
       | 
       |   return ItemFactory
       `----