Lazy loading pattern

The following pattern for lazy loading is very common:

def full_name
  @full_name ||= get_full_name
end

def get_full_name
  first_name + last_name
end

private :get_full_name

In a generic way I like to do:

def foo
  @foo ||= foo_
end

def foo_
  "Foo"
end

private :foo_

This gets boring very fast.

Was thinking in implementing a pattern like this:

lazy :foo

def foo_
  "Foo"
end

`lazy` would then implement the pattern and set `foo_` as private by
default.

Or even also a pattern in ruby where methods ending in "_" would be private
by default.

Does it make sense to you?
What are your thoughts?

Thanks,
Subtileos

lazy(:foo) do
  "Foo"
end
···

On Fri, 13 Jan 2017 at 11:08, Daniel Ferreira <subtileos@gmail.com> wrote:

The following pattern for lazy loading is very common:

def full_name
  @full_name ||= get_full_name
end

def get_full_name
  first_name + last_name
end

private :get_full_name

In a generic way I like to do:

def foo
  @foo ||= foo_
end

def foo_
  "Foo"
end

private :foo_

This gets boring very fast.

Was thinking in implementing a pattern like this:

lazy :foo

def foo_
  "Foo"
end

`lazy` would then implement the pattern and set `foo_` as private by
default.

Or even also a pattern in ruby where methods ending in "_" would be
private by default.

Does it make sense to you?
What are your thoughts?

Thanks,
Subtileos

Or why not:

Hi,

There is already a gem for this.

Regards,
James

···

On Fri, 13 Jan 2017 at 11:08 Daniel Ferreira <subtileos@gmail.com> wrote:

The following pattern for lazy loading is very common:

def full_name
  @full_name ||= get_full_name
end

def get_full_name
  first_name + last_name
end

private :get_full_name

In a generic way I like to do:

def foo
  @foo ||= foo_
end

def foo_
  "Foo"
end

private :foo_

This gets boring very fast.

Was thinking in implementing a pattern like this:

lazy :foo

def foo_
  "Foo"
end

`lazy` would then implement the pattern and set `foo_` as private by
default.

Or even also a pattern in ruby where methods ending in "_" would be
private by default.

Does it make sense to you?
What are your thoughts?

Thanks,
Subtileos

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

def lazy_foo()
   if @foo then return @foo
   @foo=foo()
end

this doesn't work. How can @foo be returned (_also if being already nil_), and the code below be executed if @foo doesn't exist?

Hi
Perhaps we could write a Module Lazy_Attr for that with
#lazy_attr, #~reader, #~writer, and #~accessor
I think this useful and needed often.
- Analog to standard attr

Opti

···

On 2017-01-13 12:08, Daniel Ferreira wrote:

The following pattern for lazy loading is very common:

In a generic way I like to do:

How about something like this:

===8<---cut here---

module Memoizer
  def memoize(name, &blk)
    var_name = "@#{name}"
    define_method(name) do
      if instance_variable_defined?(var_name)
        puts "using existing value"
        instance_variable_get(var_name)
      else
        puts "calling block"
        instance_variable_set(var_name, blk.call)
      end
    end
  end
end
# => :memoize

class Greeter
  extend Memoizer # note that's *extend*, not *include*
  memoize(:greeting) { "Hi!" }
  memoize(:farewell) { "Bye!" }
  def check_greeting
    instance_variable_get(:@greeting)
  end
  def check_farewell
    instance_variable_get(:@farewell)
  end
  def say_hi
    puts greeting
  end
  def say_bye
    puts farewell
  end
end
# => :say_bye

g = Greeter.new
# => #<Greeter:0xsomebighexnumber>

g.check_greeting
# => nil

g.say_hi
# prints "calling block" and then "Hi!"
# => nil

g.check_greeting
# => "Hi!"

g.say_hi
# prints "using existing value" and then "Hi!"
# => nil

g.check_farewell
# => nil

g.say_bye
# prints "calling block" and then "Bye!"
# => nil

g.check_farewell
# => "Bye!"

g.say_bye
# prints "using existing value" and then "Bye!"
# => nil

===8<---cut here---

Of course, remove the "puts"es for production use! :wink:

This is simple enough yet widely enough useful for those not versed in
metaprogramming themselves, that I wouldn't be at all surprised if
there's already something like this. If no, I'll gladly make a public
gem of it....

-Dave

···

On Fri, Jan 13, 2017 at 6:22 AM, Daniel Ferreira <subtileos@gmail.com> wrote:

Or why not:

lazy(:foo) do
  "Foo"
end

--
Dave Aronson, consulting software developer of Codosaur.us,
PullRequestRoulette.com, Blog.Codosaur.us, and Dare2XL.com.

Hopping on rubygems.org and searching on "memoize" reveals a large
number of them already.

···

On Fri, Jan 13, 2017 at 8:25 AM, Dave Aronson <ruby-talk.list.2.TRex@codosaur.us> wrote:

This is simple enough yet widely enough useful for those not versed
in metaprogramming themselves, that I wouldn't be at all surprised
if there's already something like this. If no, I'll gladly make a public
gem of it....

--
Dave Aronson, consulting software developer of Codosaur.us,
PullRequestRoulette.com, Blog.Codosaur.us, and Dare2XL.com.

> The following pattern for lazy loading is very common:

>

> ```

> In a generic way I like to do:

>

> ```

def lazy_foo()

   if @foo then return @foo

   @foo=foo()

end

The goal is to call `foo` in the code not `lazy_foo`

I don't think we should force a lazy method to have `lazy` word in its name.

It should be an option of the user.

···

On Fri, 13 Jan 2017 at 13:21, Die Optimisten <inform@die-optimisten.net> wrote:

On 2017-01-13 12:08, Daniel Ferreira wrote:

this doesn't work. How can @foo be returned (_also if being already

nil_), and the code below be executed if @foo doesn't exist?

Hi

Perhaps we could write a Module Lazy_Attr for that with

#lazy_attr, #~reader, #~writer, and #~accessor

I think this useful and needed often.

- Analog to standard attr

Opti

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>

<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

There are a **lot** of Ruby memoization libraries on Github.

A crude search returns 156 results for me: https://github.com/search?l=Ruby&langOverride=&q=memoization&repo=&start_value=1&type=Repositories

Click here to view Company Information and Confidentiality Notice.<http://www.jameshall.co.uk/index.php/small-print/email-disclaimer>

Hi,

There is already a gem for this.
GitHub - matthewrudy/memoist: ActiveSupport::Memoizable with a few enhancements

Regards,
James

Thanks James. Will take a look. Always good not to replicate efforts.

Regards,

Daniel

The following pattern for lazy loading is very common:

def full_name
  @full_name ||= get_full_name
end

def get_full_name
  first_name + last_name
end

private :get_full_name

In a generic way I like to do:

def foo
  @foo ||= foo_
end

def foo_
  "Foo"
end

private :foo_

This gets boring very fast.

Was thinking in implementing a pattern like this:

lazy :foo

def foo_
  "Foo"
end

`lazy` would then implement the pattern and set `foo_` as private by
default.

Or even also a pattern in ruby where methods ending in "_" would be
private by default.

Does it make sense to you?
What are your thoughts?

Thanks,
Subtileos

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>

<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>

<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

···

On Fri, 13 Jan 2017 at 13:31, James Doyley <jdoyley@gmail.com> wrote:

On Fri, 13 Jan 2017 at 11:08 Daniel Ferreira <subtileos@gmail.com> wrote:

def lazy_foo()
   if @foo then return @foo
   @foo=foo()
end

this doesn't work. # To make it clearer:
How can
     1) existing @foo be returned (_also if being already nil_),
     and 2) the code below be executed if @foo doesn't exist?

Perhaps we could write a Module Lazy_Attr for that with
#lazy_attr, #~reader, #~writer, and #~accessor
I think this useful and needed often.
- Analog to standard attr

Opti

···

On 2017-01-13 14:20, Die Optimisten wrote:

On 2017-01-13 12:08, Daniel Ferreira wrote:

The following pattern for lazy loading is very common:

In a generic way I like to do:

ok, you have to know the keyword "memoization" to find that...

Opti

···

On 2017-01-13 14:26, Andy Jones wrote:

There are a **lot** of Ruby memoization libraries on Github.

A crude search returns 156 results for me: Repository search results · GitHub

Click here to view Company Information and Confidentiality Notice.<http://www.jameshall.co.uk/index.php/small-print/email-disclaimer&gt;

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

The common idiom is to check if it's already defined: return @foo if
defined? @foo

···

On Fri, Jan 13, 2017 at 5:25 AM, Die Optimisten <inform@die-optimisten.net> wrote:

On 2017-01-13 14:20, Die Optimisten wrote:

On 2017-01-13 12:08, Daniel Ferreira wrote:

The following pattern for lazy loading is very common:

In a generic way I like to do:

def lazy_foo()
  if @foo then return @foo
  @foo=foo()
end

this doesn't work. # To make it clearer:
How can
    1) existing @foo be returned (_also if being already nil_),
    and 2) the code below be executed if @foo doesn't exist?

Perhaps we could write a Module Lazy_Attr for that with
#lazy_attr, #~reader, #~writer, and #~accessor
I think this useful and needed often.
- Analog to standard attr

Opti

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;