title: Is this define_method use case too complex?
body: <p>I've been bashing my head against this for about three days now. I've created a class that models html pages and tells cucumber step definitions where to populate form data:</p>
  
  <pre><code>class FlightSearchPage
  
    def initialize(browser, page, brand)
      @browser = browser
      @start_url = page
  
      #Get reference to config file
      config_file = File.join(File.dirname(__FILE__), '..', 'config', 'site_config.yml')
  
      #Store hash of config values in local variable
      config = YAML.load_file config_file
  
      @brand = brand #brand is specified by the customer in the features file
  
      #Define instance variables from the hash keys
      config.each do |k,v|
        instance_variable_set("@#{k}",v)
      end
    end
  
    def method_missing(sym, *args, &amp;block)
      @browser.send sym, *args, &amp;block
    end
  
    def page_title
      #Returns contents of &lt;title&gt; tag in current page.
      @browser.title
    end
  
    def visit
      @browser.goto(@start_url)
    end
  
    def set_origin(origin)
      self.text_field(@route[:attribute] =&gt; @route[:origin]).set origin
    end
  
    def set_destination(destination)
      self.text_field(@route[:attribute] =&gt; @route[:destination]).set destination
    end
  
    def set_departure_date(outbound)
      self.text_field(@route[:attribute]  =&gt; @date[:outgoing_date]).set outbound
    end
  
    # [...snip]
  
  end
  </code></pre>
  
  <p>As you can see, I've used instance_variable_set to create the variables that hold the references on the fly, and the variable names and values are supplied by the config file (which is designed to be editable by people who aren't necessarily familiar with Ruby).</p>
  
  <p>Unfortunately, this is a big, hairy class and I'm going to have to edit the source code every time I want to add a new field, which is obviously bad design so I've been trying to go a stage further and create the methods that set the variable names dynamically with define_method and this is what's kept me awake until 4am for the last few nights.</p>
  
  <p>This is what I've done:</p>
  
  <pre><code>require File.expand_path(File.dirname(__FILE__) + '/flight_search_page')
  
  class SetFieldsByType &lt;  FlightSearchPage
    def text_field(config_hash)
      define_method(config_hash) do |data|
        self.text_field(config_hash[:attribute] =&gt; config_hash[:origin]).set data
      end
    end
  end
  </code></pre>
  
  <p>The idea is that all you need to do to add a new field is add a new entry to the YAML file and define_method will create the method to allow cucumber to populate it.</p>
  
  <p>At the moment, I'm having problems with scope - Ruby thinks that define_method is a member of @browser. But what I want to know is: is this even feasible? Have I totally misunderstood  define_method? </p>