Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > lazy lookup

Reply
Thread Tools

lazy lookup

 
 
Thomas Hafner
Guest
Posts: n/a
 
      05-02-2009
Hello,

how about the following implementation for lazy lookups?

def define_lookup
h = lambda{ |k|
h = {}
# ... fill h (expensive!) ...
h[k]
}
self.class.class_eval{ define_method(:lookup){ |k| h[k] } }
end

Once ``define_lookup'' has been called, the method ``lookup'' is
defined and will act in a lazy manner. Just call ``lookup'' as often
as you need, but only for the first time the expensive operation (e.g.
dealing with files) will be performed. Due to duck typing no condition
needs to be checked: for the first call ``h[k]'' implies calling the
lambda, for the next times ``h[k]'' implies accessing the hash.

(Tried with Ruby 1.8.6.)

Regards
Thomas
 
Reply With Quote
 
 
 
 
Robert Klemme
Guest
Posts: n/a
 
      05-02-2009
On 02.05.2009 15:33, Thomas Hafner wrote:
> Hello,
>
> how about the following implementation for lazy lookups?
>
> def define_lookup
> h = lambda{ |k|
> h = {}
> # ... fill h (expensive!) ...
> h[k]
> }
> self.class.class_eval{ define_method(:lookup){ |k| h[k] } }
> end
>
> Once ``define_lookup'' has been called, the method ``lookup'' is
> defined and will act in a lazy manner. Just call ``lookup'' as often
> as you need, but only for the first time the expensive operation (e.g.
> dealing with files) will be performed. Due to duck typing no condition
> needs to be checked: for the first call ``h[k]'' implies calling the
> lambda, for the next times ``h[k]'' implies accessing the hash.
>
> (Tried with Ruby 1.8.6.)


Sorry to sound discouraging but there is memoize already. The
difference is that not the whole Hash is filled but only the one that
you need for the argument list provided which seems potentially more
efficient.

define_lookup should probably be a class method but in that case having
a single Hash for all instances is problematic.

Note, that you can use Hash's default_proc to achieve something similar
very elegantly:

class Foo
def initialize(some, args)
@some = some
@args = args
@lookup = Hash.new {|h,k| h[k] = do_lookup(k)}
end

def lookup(a,b)
@lookup[[a,b]]
end

private
def do_lookup(args)
puts "calculating..."
sleep 2
args.first + args.last + @some + @args
end
end

Note that you do not need a separate method but if the calculation is
complex code might be more readable with another method.

irb(main):059:0> f = Foo.new 1,2
=> #<Foo:0x101b3ce8 @some=1, @args=2, @lookup={}>
irb(main):060:0> f.lookup 3,4
calculating...
=> 10
irb(main):061:0> f.lookup 3,4
=> 10
irb(main):062:0>

In case you want to fill the Hash completely you can just replace the
calculation code to assign multiple values.

OTOH, often a single Hash with a default_proc is sufficient already, e.h.

irb(main):064:0> foo = Hash.new {|h,k| h[k] = k + 1 + 3}
=> {}
irb(main):065:0> foo[3]
=> 7
irb(main):066:0> foo
=> {3=>7}

Kind regards

robert

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 
Reply With Quote
 
 
 
 
Thomas Hafner
Guest
Posts: n/a
 
      05-03-2009
Robert Klemme <> wrote/schrieb <>:

> Sorry to sound discouraging but there is memoize already. The
> difference is that not the whole Hash is filled but only the one
> that you need for the argument list provided which seems potentially
> more efficient.


In my situation this ist not the case. The key value pairs can be
retrieved by reading a file. It's better to open/read/close the file
only once and retrieve all key value pairs at the same time. Of course
the file should not be read at all, if never a value will be
requested.

> In case you want to fill the Hash completely you can just replace the
> calculation code to assign multiple values.


How does that look like? Somethink like that?:

Hash.new{ |h,k| h.replace(
COMPLETELY_CALCULATED_HASH
); h[k] }

(COMPLETELY_CALCULATED_HASH should be replaced by some code which
calculates the hash completely)

Regards
Thomas
 
Reply With Quote
 
Robert Klemme
Guest
Posts: n/a
 
      05-04-2009
2009/5/4 Thomas Hafner <>:
> Robert Klemme <> wrote/schrieb <763388F1amqkuU1=

@mid.individual.net>:
>
>> Sorry to sound discouraging but there is memoize already. The
>> difference is that not the whole Hash is filled but only the one
>> that you need for the argument list provided which seems potentially
>> more efficient.

>
> In my situation this ist not the case. The key value pairs can be
> retrieved by reading a file. It's better to open/read/close the file
> only once and retrieve all key value pairs at the same time. Of course
> the file should not be read at all, if never a value will be
> requested.
>
>> In case you want to fill the Hash completely you can just replace the
>> calculation code to assign multiple values.

>
> How does that look like? Somethink like that?:
>
> =A0Hash.new{ |h,k| h.replace(
> =A0 =A0 =A0COMPLETELY_CALCULATED_HASH
> =A0 =A0); h[k] }


> (COMPLETELY_CALCULATED_HASH should be replaced by some code which
> calculates the hash completely)


I don't see the need for #replace. You can as well hand over h to the
routine that fetches the data. But otherwise yes. As a safety
measure you would probably also remember that you have loaded the Hash
in an instance variable of h.

Kind regards

robert


--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

 
Reply With Quote
 
Robert Klemme
Guest
Posts: n/a
 
      05-04-2009
2009/5/4 Robert Klemme <>:
>> How does that look like? Somethink like that?:
>>
>> =A0Hash.new{ |h,k| h.replace(
>> =A0 =A0 =A0COMPLETELY_CALCULATED_HASH
>> =A0 =A0); h[k] }


PS: careful with h[k] at the end: you might create an infinite loop
unless you are sure that k is in the Hash.

Cheers

robert

--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
lazy evaluation is sometimes too lazy... help please. Ken Pu Python 3 01-16-2009 11:23 AM
Re: lazy evaluation is sometimes too lazy... help please. Boris Borcic Python 0 01-16-2009 10:46 AM
Re: lazy evaluation is sometimes too lazy... help please. Boris Borcic Python 0 01-16-2009 10:37 AM
hello! first post to clr. I'm asking about an attempt at a lazy rubysolution to computing fibonacci numbers for a project euler problem. seems tobe a bug in lazy ruby... tphyahoo Ruby 6 08-08-2008 08:15 PM
Reg Ex Help for a Lazy VB Programmer adams114@comcast.net Perl 6 04-21-2004 08:27 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57