Johan Eriksson
4/26/2008 5:57:00 PM
Hi --
David A. Black wrote:
> Hi --
>
> On Sat, 26 Apr 2008, Johan Eriksson wrote:
>
>> Hi --
>>
>> David A. Black wrote:
>>> Hi --
>>>
>>> On Sat, 26 Apr 2008, Johan Eriksson wrote:
>>>
>>>> Hi --
>>>>
>>>> David A. Black wrote:
>>>>> Hi --
>>>>>
>>>>> On Sat, 26 Apr 2008, Johan Eriksson wrote:
>>>>>
>>>>>> Chris Hulan wrote:
>>>>>>> On Apr 25, 11:16 am, Johan Eriksson <jo...@johaneriksson.se> wrote:
>>>>>>>> Hi!
>>>>>>>>
>>>>>>>> I have some troubles with this.
>>>>>>>>
>>>>>>>> obj_as_list.each do |att|
>>>>>>>> if att[1].is_a?(String)
>>>>>>>> att[1] = "'#{att[1]'"
>>>>>>> You're missing a '}' here ----------^
>>>>>>>
>>>>>>> does that help?
>>>>>>>
>>>>>>
>>>>>> Nope. I am providing the surrounding function here. (It is defined
>>>>>> inside a class.)
>>>>>>
>>>>>> def load_from_file(filename)
>>>>>> require 'yaml'
>>>>>> yaml_dict = YAML::load(File.open(filename))
>>>>>> object_list = [] #The list that should be returned
>>>>>> yaml_dict[yaml_dict.keys[0]].each do |yaml_obj|
>>>>>> new_obj = self.class.new
>>>>>> yaml_obj.each do |obj|
>>>>>> obj_as_list = obj.to_a
>>>>>> obj_as_list.each do |att|
>>>>>> if att[1].is_a?(String)
>>>>>> att[1] = "'#{att[1]}'"
>>>>>> end
>>>>>> str = "new_obj.#{att[0]} = #{att[1]}"
>>>>>> eval(str)
>>>>>> end
>>>>>> end
>>>>>> object_list << new_obj
>>>>>> end
>>>>>> object_list
>>>>>> end
>>>>>>
>>>>>> And the error:
>>>>>>
>>>>>> NameError: undefined local variable or method `att' for
>>>>>> main:Object
>>>>>
>>>>> If att[1] is, say, :att, then "#{att[1]}" is "att" and you've got a
>>>>> dangling att. The whole eval thing seems extremely fragile (which eval
>>>>> things usually are). I imagine there's a more robust and probably
>>>>> shorter way to do this, but I'm not sure what the data coming in and
>>>>> out are supposed to be like.
>>>>>
>>>>>
>>>>> David
>>>>>
>>>>
>>>> I am almost positive that there is, given that I'm pretty much a
>>>> noob at ruby. The whole thing is a class_eval too. The idea is to
>>>> add this function to a class that has just been created based on a
>>>> textfile. The function will receive a file that includes a yaml
>>>> description of instances of the class, and the function then makes
>>>> these instances and sends them back as a list. I think some
>>>> fragility is okay, though I'd be keen on learning better ways to do
>>>> this. Around the entire function is
>>>>
>>>> the_class.class_eval %{
>>>> the function...
>>>> }
>>>>
>>>> I am confused about why it doesn't work though.
>>>
>>> Can you give some sample YAML input? I'm still not quite picturing it.
>>>
>>>
>>> David
>>
>> This is a simple example:
>>
>> dogs:
>> - name : Fido
>> age : 2
>>
>> - name : Rufus
>>
>> - name : Doggie
>> age : 4
>>
>> - name : Puppy
>> age : 1
>>
>> The function should then create four instances of dog, assign them the
>> names and ages specified, put them in a list and return them.
>>
>> Thanks for taking the time to help me out!
>
> Why not do this (or something similar):
>
> require 'yaml'
>
> class Dog
> attr_accessor :name, :age
> end
>
> animals = YAML.load(<<EOA)
> dogs:
> - name : Fido
> age : 2
>
> - name : Rufus
>
> - name : Doggie
> age : 4
>
> - name : Puppy
> age : 1
> EOA
>
> dogs = animals["dogs"]
> dog_objects = dogs.map do |name,age|
> d = Dog.new
> d.name = name
> d.age = age
> d
> end
>
> p dog_objects
>
>
> David
>
Thanks a lot! I think this will be very helpful. I didn't know map
worked like this. I'll need to adapt it to work even though I don't know
the name of the class in advance, but that's workable, right?
/Johan
--