lib/respect/core_statements.rb
def method_missing(method_name, *args, &block)
      if respond_to_missing?(method_name, false)
        size_range = 1..2
        if size_range.include? args.size
          name = args.shift
          default_options = {}
          default_options.merge!(@options) unless @options.nil?
          default_options[:doc] = @doc unless @doc.nil?
          if options = args.shift
            options = default_options.merge(options)
          else
            options = default_options
          end
          @doc = nil
          update_context name, Respect.schema_for(method_name).define(options, &block)
        else
          expected_size = args.size > size_range.end ? size_range.end : size_range.begin
          raise ArgumentError, "wrong number of argument (#{args.size} for #{expected_size})"
        end
      else
        super
      end
    end
def method_missing(method_name, *args, &block)
      if respond_to_missing?(method_name, false)
        size_range = 1..2
        if size_range.include? args.size
          name = args.shift
          default_options = {}
          default_options.merge!(@options) unless @options.nil?
          default_options[:doc] = @doc unless @doc.nil?
          if options = args.shift
            options = default_options.merge(options)
          else
            options = default_options
          end
          @doc = nil
          update_context name, Respect.schema_for(method_name).define(options, &block)
        else
          expected_size = args.size > size_range.end ? size_range.end : size_range.begin
          raise ArgumentError, "wrong number of argument (#{args.size} for #{expected_size})"
        end
      else
        super
      end
    end
@!method string(name, options = {})
   Define a {StringSchema} with the given +options+ and stores it in the
   current context using +name+ as index.
 @!method integer(name, options = {})
   Define a {IntegerSchema} with the given +options+ and stores it in the
   current context using +name+ as index.
 @!method float(name, options = {})
   Define a {FloatSchema} with the given +options+ and stores it in the
   current context using +name+ as index.
 @!method numeric(name, options = {})
   Define a {NumericSchema} with the given +options+ and stores it in the
   current context using +name+ as index.
 @!method any(name, options = {})
   Define a {AnySchema} with the given +options+ and stores it in the
   current context using +name+ as index.
 @!method null(name, options = {})
   Define a {NullSchema} with the given +options+ and stores it in the
   current context using +name+ as index.
 @!method boolean(name, options = {})
   Define a {BooleanSchema} with the given +options+ and stores it in the
   current context using +name+ as index.
 @!method uri(name, options = {})
   Define a {URISchema} with the given +options+ and stores it in the
   current context using +name+ as index.
 @!method hash(name, options = {}, &block)
   Define a {HashSchema} with the given +options+ and +block+ stores it
   in the current context using +name+ as index.
 @!method array(name, options = {})
   Define a {ArraySchema} with the given +options+ and +block+ stores it
   in the current context using +name+ as index.
 @!method datetime(name, options = {})
   Define a {DatetimeSchema} with the given +options+ and stores it in the
   current context using +name+ as index.
 @!method ip_addr(name, options = {})
   Define a {IPAddrSchema} with the given +options+ and stores it in the
   current context using +name+ as index.
 @!method ipv4_addr(name, options = {})
   Define a {Ipv4AddrSchema} with the given +options+ and stores it in the
   current context using +name+ as index.
 @!method ipv6_addr(name, options = {})
   Define a {Ipv6AddrSchema} with the given +options+ and stores it in the
   current context using +name+ as index.
 @!method regexp(name, options = {})
   Define a {RegexpSchema} with the given +options+ and stores it in the
   current context using +name+ as index.
 @!method utc_time(name, options = {})
   Define a {UTCTimeSchema} with the given +options+ and stores it in the
   current context using +name+ as index.

 Call +update_context+ using the first argument as index and passes the rest
 to the {Schema.define} class method of the schema class associated with the method name.
 As a consequence any call to missing method +foo+ will define a +FooSchema+
 schema using +FooSchema.define+.

 The options are merged with the default options which may include the +:doc+
 option if {#doc} has been called before. The current documentation is reset
 after this call.

 Note that if you define a new schema named after a method already defined in
 a context class such as {GlobalDef} or its sub-classes or in +Object+, the
 dynamic dispatch won't work. For instance even if you have defined the
 +ClassSchema+ class the following code won't work as expected:

   Schema.define do |s|
     s.class  # Call Object#class !!!!!
   end

 To prevent this problem you must undefine the method in the DSL by doing
 something like that:

   module Respect
     class GlobalDef
       undef_method :class
     end
   end

 or you can override the +class+ method in the context of your choice:

   module Respect
     class GlobalDef
       def class(name, options = {}, &block)
         update_context name, ClassSchema.define(options, &block)
       end
     end
   end

 Do not un-define or override 'method' and 'methods' since {FakeNameProxy}
 use them.