From: Benjamin Kudria on 7 Jul 2010 20:29 I'm trying to extend OpenStruct for an application I'm building, where I'd like to access nested hashes as models. OpenStruct (in core) sounds perfect for this, but I ran into two problems: - Recursion My hashes have nested hashes, and I want to convert *those* to objects, too. I was able to solve this problem pretty easily, see the to_self method in the linked code [1]. However, this made me run into the second problem - speed. I was loading rather large documents, and it was taking quite a bit of time to go through them, instantiating classes for everything. I though I'd make the code lazy-load, using the lazy.rb [0] However, I overrode some more core methods for OpenStruct, to create promises, and demand them, but now the code simply produces incorrect results. In IRB, I do: > LazyStruct.new({:a=>1, :b => 2}).a But my result is 2, not 1. The code is here: http://gist.github.com/467459 What could be going wrong? Any inishgt would be appreciatted. I'm using Ruby 1.9.2-preview3 (Apologies for the Railsisms, this is part of a Rails project. The classify method turns things into a string resembling a class, and constantize turns that string into a constant - hopefully a class. This code is bypassed in my simple example.) 0: http://github.com/mental/lazy Thanks! Benjamin Kudria ben(a)kudria.net -- Posted via http://www.ruby-forum.com/.
From: Intransition on 7 Jul 2010 21:39 On Jul 7, 8:29 pm, Benjamin Kudria <b...(a)kudria.net> wrote: > I'm trying to extend OpenStruct for an application I'm building, where > I'd like to access nested hashes as models. OpenStruct (in core) sounds > perfect for this, but I ran into two problems: > > - Recursion > My hashes have nested hashes, and I want to convert *those* to > objects, too. I was able to solve this problem pretty easily, see the > to_self method in the linked code [1]. > > However, this made me run into the second problem - speed. I was loading > rather large documents, and it was taking quite a bit of time to go > through them, instantiating classes for everything. I though I'd make > the code lazy-load, using the lazy.rb [0] > > However, I overrode some more core methods for OpenStruct, to create > promises, and demand them, but now the code simply produces incorrect > results. > > In IRB, I do: > > > LazyStruct.new({:a=>1, :b => 2}).a > > But my result is 2, not 1. The code is here:http://gist.github.com/467459 > > What could be going wrong? Any inishgt would be appreciatted. I'm using > Ruby 1.9.2-preview3 Not 100%, but maybe have a look at Hashery's OpenCascade for some ideas (http://rubyworks.github.com/hashery). I think you can do the lazy lookup without using a Promise.
From: Michael Jackson on 7 Jul 2010 22:32 I've done something similar that's pretty lightweight. My version actually extends Hash, so it should be pretty fast and you get all the niceties of Hash for free. http://mjijackson.com/symboltable http://github.com/mjijackson/symboltable -- Michael Jackson http://mjijackson.com @mjijackson On Wed, Jul 7, 2010 at 6:29 PM, Benjamin Kudria <ben(a)kudria.net> wrote: > I'm trying to extend OpenStruct for an application I'm building, where > I'd like to access nested hashes as models. OpenStruct (in core) sounds > perfect for this, but I ran into two problems: > > - Recursion > My hashes have nested hashes, and I want to convert *those* to > objects, too. I was able to solve this problem pretty easily, see the > to_self method in the linked code [1]. > > However, this made me run into the second problem - speed. I was loading > rather large documents, and it was taking quite a bit of time to go > through them, instantiating classes for everything. I though I'd make > the code lazy-load, using the lazy.rb [0] > > However, I overrode some more core methods for OpenStruct, to create > promises, and demand them, but now the code simply produces incorrect > results. > > In IRB, I do: >> LazyStruct.new({:a=>1, :b => 2}).a > > But my result is 2, not 1. The code is here: > http://gist.github.com/467459 > > What could be going wrong? Any inishgt would be appreciatted. I'm using > Ruby 1.9.2-preview3 > > (Apologies for the Railsisms, this is part of a Rails project. The > classify method turns things into a string resembling a class, and > constantize turns that string into a constant - hopefully a class. This > code is bypassed in my simple example.) > > 0: http://github.com/mental/lazy > > Thanks! > Benjamin Kudria > ben(a)kudria.net > -- > Posted via http://www.ruby-forum.com/. > >
From: Benjamin Kudria on 8 Jul 2010 00:18 Michael Jackson wrote: > I've done something similar that's pretty lightweight. My version > actually extends Hash, so it should be pretty fast and you get all the > niceties of Hash for free. Michael, thanks for the pointer, but I don't really see how it helps. Your code doesn't support recursive conversion, or lazy property retrieval. I'm content with using OpenStruct for all the functionality your code provides. Thomas Sawyer wrote: > Not 100%, but maybe have a look at Hashery's OpenCascade for some > ideas (http://rubyworks.github.com/hashery). I think you can do the > lazy lookup without using a Promise. Indeed, my initial version didn't use mental's library, but I had to reach way deeper into OpenStruct to make the appropriate changes. OpenCascade is awesome! But,I left out a small detail of my implementation that is actually rather important - my to_self method actually tries to find a class corresponding to the name of the key (the classify.constantize call) and use that if available. So, {:authors => [{:name => 'Poe'}, {:name => 'Lovecraft'}]} would actually end up converting to two Author objects, if the class were available, passing the hash to the initialize method. This functionality is important to me, it allows me to hang business logic on sub-documents in my overall document. OpenCascade, it seems, converts only to OpenCascade. (I may take a detour and subclass OpenCascade instead, modify it to support my auto-classifying,, and compare the two approaches.) Fortunately, mental clued me into the problem with my code [1] shortly after I posted this. For future reference, I was creating the promise (with its associated block) and closing over the same k and v variables, instead of creating a new scope every time. I separated the call out to a method, and everything worked. Benjamin Kudria ben(a)kudria.net 1: http://twitter.com/mentalguy/status/17993170022 and http://twitter.com/mentalguy/status/17993202421 -- Posted via http://www.ruby-forum.com/.
|
Pages: 1 Prev: [ANN] Win32::Screenshot 0.0.5 Next: Changing registry values with Win32::Registry |