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
       `----