Where do you require?

I was reading through some of Why's parkplace code this afternoon, and I saw a couple things I wanted to ask people about. (http://code.whytheluckystiff.net/parkplace/browser/trunk/lib/parkplace.rb)

1) What's the effect of doing a require inside a method like in ParkPlace#config or ParkPlace#serve? It's just a method right, so it will re-require every time the method is called? Since it's getting loaded inside a method does it garbage collect the library after the method returns? (Maybe do it to save memory?) What's the behavior with bindings that use dynamically linked libraries?

2) What is this type of class definition all about:

module ParkPlace
   class << self
     def foo
     end
   end
end

It seems to be creating singleton methods the same as doing this, except with more typing:

module ParkPlace
   def ParkPlace.foo # or def self.foo
   end
end

Thanks,
Jeff

I was reading through some of Why's parkplace code this afternoon, and I saw a couple things I wanted to ask people about. (http://code.whytheluckystiff.net/parkplace/browser/trunk/lib/parkplace.rb\)

1) What's the effect of doing a require inside a method like in ParkPlace#config or ParkPlace#serve? It's just a method right, so it will re-require every time the method is called? Since it's getting loaded inside a method does it garbage collect the library after the method returns? (Maybe do it to save memory?) What's the behavior with bindings that use dynamically linked libraries?

require only loads a given file once regardless of how many times it's called. I believe _why is doing the require's in methods so that a) it only goes to the disk to require something if it's _really_ needed and b) He's putting the require as close as possible to the place where it's actually used so that when reading the code you don't see a bunch of requires at the top and wonder where in the code they are used. Regardless the require still acts globally.

2) What is this type of class definition all about:

module ParkPlace
  class << self
    def foo
    end
  end
end

It seems to be creating singleton methods the same as doing this, except with more typing:

module ParkPlace
  def ParkPlace.foo # or def self.foo
  end
end

That's exactly what it is. OTOH it's only more typing if you're only creating one or two methods, e.g.:

class ParkPlace
   class << self
     def foo
     end

     def bar
     end

     def baz
     end
end

v.s.

class ParkPlace
   def self.foo
   end

   def self.bar
   end

   def self.baz
   end
end

···

On May 10, 2006, at 10:49 AM, Jeff Rose wrote:

Thanks,
Jeff

I was reading through some of Why's parkplace code this afternoon, and I
saw a couple things I wanted to ask people about.
(http://code.whytheluckystiff.net/parkplace/browser/trunk/lib/parkplace.rb\)

1) What's the effect of doing a require inside a method like in
ParkPlace#config or ParkPlace#serve? It's just a method right, so it
will re-require every time the method is called? Since it's getting
loaded inside a method does it garbage collect the library after the
method returns? (Maybe do it to save memory?) What's the behavior with
bindings that use dynamically linked libraries?

It will only get loaded once. (In the first call to #require its name will get
added to $", which is checked against before loading a file via require).
Placing the call to #require inside the method is but a way to load code
lazily.

As for the code being GC'd, it will all depend on whether something still
holds a reference to the associated NODEs or not. If the constant that refers
to a class/module is removed and there are no instances (or UnboundMethod
objects, etc...) left, the code will be GCed (as would an old instance method
when you redefine it).

2) What is this type of class definition all about:

module ParkPlace
  class << self
    def foo
    end
  end
end

It seems to be creating singleton methods the same as doing this, except
with more typing:

module ParkPlace
  def ParkPlace.foo # or def self.foo
  end
end

class << self; ... end introduces a new scope. It's useful in cases like
  class X
    class << self
      attr_reader :foo # getter for the class instance variable
    end
    ...
  end

···

On Wed, May 10, 2006 at 11:49:37PM +0900, Jeff Rose wrote:

--
Mauricio Fernandez - http://eigenclass.org - singular Ruby

Hi, Jeff,

Jeff Rose wrote:

I was reading through some of Why's parkplace code this afternoon, and I
saw a couple things I wanted to ask people about.
(http://code.whytheluckystiff.net/parkplace/browser/trunk/lib/parkplace.rb\)

1) What's the effect of doing a require inside a method like in
ParkPlace#config or ParkPlace#serve? It's just a method right, so it
will re-require every time the method is called? Since it's getting
loaded inside a method does it garbage collect the library after the
method returns? (Maybe do it to save memory?) What's the behavior with
bindings that use dynamically linked libraries?

Require only loads any library once. So, yes, require will be called
each time the method is called, but it will only load the library the
first time.

2) What is this type of class definition all about:

module ParkPlace
  class << self
    def foo
    end
  end
end

It seems to be creating singleton methods the same as doing this, except
with more typing:

module ParkPlace
  def ParkPlace.foo # or def self.foo
  end
end

Yes, it's the same. It makes more sense if you have a number of class
methods -- it becomes a way of grouping them together in your code, and
makes the method names ("def" lines) easier on the eye.

Cheers,
Dave