From: Intransition Date: 2010-09-25T17:10:45+09:00 Subject: Re: Ruby-based data language On Sep 22, 11:37 am, Brian Candler wrote: > > If yes: then it looks like you're proposing an alternative syntax for > > Hash literals - one which isn't widely used. It's Ruby-inspired but not > > really Ruby, since a simple eval of the above will fail without > > additional supporting code. > > That is, to parse that record using eval I think you need something > along these lines: > > class Parser # < BasicObject ?? >   def self.parse(*args, &blk) >     o = new >     o.instance_eval(*args, &blk) >     o.instance_variable_get(:@value) >   end > >   def initialize >     @value = {} >   end > >   def method_missing(label, value=:__MISSING__,&blk) >     if value != :__MISSING__ >       raise "Cannot provide both value and block for #{label}" if > block_given? >       @value[label] = value >     else >       raise "Must provide value or block for #{label}" unless > block_given? >       @value[label] = self.class.parse(&blk) >     end >   end > end > > person = Parser.parse <<'EOS' >   name "Joe Foo" >   age 33 >   contact do >     email "j...@joefoo.com" >     phione "555-555-1234" >   end > EOS > p person > > Now, to get the same capabilities as JSON, you also need syntax for > Arrays. You could do something like the following, although note that > the parser above doesn't handle this properly: > >   people([ >     person do >       name "Joe" >       age 33 >     end, >     person do >       name "Fred" >       age 64 >     end, >   ]) > > You do need both parentheses and square brackets, unless you replace > do/end with braces: > >   people [ >     person { >       name "Joe" >       age 33 >     }, >     person { >       name "Fred" >       age 64 >     }, >   ] > > Add a few colons and commas and you're back to JSON. Or drop the closing > braces and brackets and keep the indentation, and you're back to YAML. > > You could treat multiple arguments as an array: > >   people \ >     person { >       name "Joe" >       age 33 >     }, >     person { >       name "Fred" >       age 64 >     } > > but then if you wanted a one-element array it would have to be a special > case. Or you could perhaps have a flag to indicate that you want an > Array: > >   people [], >     person { >       name "Joe" >       age 33 >     }, >     person { >       name "Fred" >       age 64 >     } You make a good point about arrays. I'm thinking about configuration files as the common use case, so complex arrays aren't as common. But, maybe there are better solutions in anycase: people do person :name=>"Joe", :age=>33, preson :name=>"Fred", :age=> 64 end The format is Ruby syntax so it can handle hash arguments. Or, alternately: people ["Joe", 33], ["Fred", 64] The underlying app would know how to turn this into persons. We might even do: people ['name', 'age'], ['Joe', 33], ['Fred', 64]