Style: where to require in libs?

When writing libraries for other programs to use
is it better to include any outside requirements
within the Class definition or outside it? i.e.

[1]
require “foo”

Class Bar

end

or

[2]
Class Bar
require “foo”

end

 If my understanding is correct, 2 is politer in that you

don’t pollute the global namespace with the class defines in
foo. But I most often see [1] in existing ruby libraries. Is
there more to this than I understand?

    • Booker C. Bense
···

[1] and [2] have the same effect for ruby interpreter at all because
namespace will not be nested by require' orload’.

A human may get a little different sense from them: [1] says this library or script requires "foo"' whereas [2] saysthis definition of
class Bar requires “foo”’. But this is a problem of taste or calture.
[1] can list all required libraries on the top of a program but [2]
doesn’t. That may helps the reader expect something to use. On the
other hand, [2] points what feature depends on the libraries but [1]
doesn’t. That may be helpful to track the dependency (hopefully
correct).

There is another story if `require’ is put in def statement. Inside
of def would not be evaluated until the method is invoked. So require
in def can postpone loading a library file until really needed. That
may improve average performance in some cases.

– Gotoken

···

At Fri, 2 Aug 2002 07:33:03 +0900, bbense+comp.lang.ruby.Aug.01.02@telemark.stanford.edu wrote:

When writing libraries for other programs to use

is it better to include any outside requirements
within the Class definition or outside it? i.e.

[1]
require “foo”

Class Bar

end

or

[2]
Class Bar
require “foo”

end

…and make debugging harder. But aren’t we all doing unit testing? :slight_smile:

-billy.

···

On Fri, Aug 02, 2002 at 08:35:32AM +0900, GOTO Kentaro wrote:

There is another story if `require’ is put in def statement. Inside
of def would not be evaluated until the method is invoked. So require
in def can postpone loading a library file until really needed. That
may improve average performance in some cases.


Meisterbohne Söflinger Straße 100 Tel: +49-731-399 499-0
eLösungen 89077 Ulm Fax: +49-731-399 499-9

In article 200208012333.g71NXWiG001635@miso.k.notwork.org,

When writing libraries for other programs to use

is it better to include any outside requirements
within the Class definition or outside it? i.e.

[1]
require “foo”

Class Bar

end

or

[2]
Class Bar
require “foo”

end

[1] and [2] have the same effect for ruby interpreter at all because
namespace will not be nested by require' orload’.

    • So require is not just a “smart” include, but something that
      works at the language level[1]. If I understand you correctly,
      you can only “hide” a class definition in another class by
      keeping it in the same file. Thanks for the clarification.
      I keep having to “unlearn” my C and Perl intiutions. ( One
      of the things that attracted me to Ruby in the first place.)
    • Booker C. Bense

[1]- It’s a command not a preprocessor.

···

GOTO Kentaro gotoken@notwork.org wrote:

At Fri, 2 Aug 2002 07:33:03 +0900, >bbense+comp.lang.ruby.Aug.01.02@telemark.stanford.edu wrote:

:slight_smile:

By the way, unit testing is big fun but useful only if that testing is
done thoroughgoingly. For example, a bug by require-in-def would be
missed detecting if the method is skipped in a test. Now, I wrote a
coverage testrunner, subclass of Test::Unit::UI::CONSOLE::TestRunner:
http://www.notwork.org/~gotoken/ruby/p/as-is/testrunner_coverage.rb
This is very ad hoc one but I found some missing tests by this toy.
Test first? I know I know… but I often forget it :wink:
More sophisticated coverage test may help the unit test to complete? (#)

(#) NaHi told me this idea, not mine.

···

At Fri, 2 Aug 2002 18:33:59 +0900, Philipp Meier wrote:

On Fri, Aug 02, 2002 at 08:35:32AM +0900, GOTO Kentaro wrote:

There is another story if `require’ is put in def statement. Inside
of def would not be evaluated until the method is invoked. So require
in def can postpone loading a library file until really needed. That
may improve average performance in some cases.

…and make debugging harder. But aren’t we all doing unit testing? :slight_smile:

Yes. require doesn’t “insert” code there. require only loads a
library, i.e., reads and evaluates that always in the top level
context unless already loaded.

A Ruby code has identical semantics regardless of require’d or
directly invoked:

% cat ./usee.rb
def a(arg)
[FILE, arg, self]
end
p [1, a(FILE)]

% ruby ./usee.rb
[1, ["./usee.rb", “./usee.rb”, main]]

% cat ./user.rb
class C
require "usee"
p [2, a(FILE)]
end
require "usee"
p [3, a(FILE)]
p [4, C.public_methods.include?(“a”)]
p [5, Object.private_methods.include?(“a”)]

% ruby ./user.rb
[1, ["./usee.rb", “./usee.rb”, main]]
[2, ["./usee.rb", “./user.rb”, C]]
[3, ["./usee.rb", “./user.rb”, main]]
[4, false]
[5, true]

[5] because a method defined in top level is a function, i.e., a

private method of Object, that is, could not be called with explict

receiver.

In other word, Ruby’s require is similar to Emacs-Lisp’s require,
which never loads a library twice and doesn’t change the meaning of a
library to be loaded.

– Gotoken

···

At Sat, 3 Aug 2002 03:14:44 +0900, bbense+comp.lang.ruby.Aug.02.02@telemark.stanford.edu wrote:

[1] and [2] have the same effect for ruby interpreter at all because
namespace will not be nested by require' orload’.

    • So require is not just a “smart” include, but something that
      works at the language level[1].