-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hello List,
I’m trying to understand the way Ruby resolves symbol names and how the
require statement fits in.
I’ll start right away with an example, which comes in two files (note
the
comments):
a.rb:
require ‘a/b’
module Foo
class Foo::A
def do_something()
b = Foo::A::B.new
b.say
end
end
a/b.rb:
require ‘a’
module Foo
class Foo:
:B < Foo::A
def say
puts “Hello, World”
end
end
end
With the above code, I get a “missing symbol” error. Placing the
“require
‘a/b’” statement within the Foo::A class remedies it.
Now I’m not quite sure why. I know that require() is a statement like
puts
in regards of its execution time, i.e. there’s no special treatment in
some
parse/compile/whatever phase before the actual execution begins. As
such, it
seems logic that I get the missing symbol error with the original code:
Foo::A is not defined when the derivation is made, and as such, putting
require ‘a/b’ some lines later helps.
Am I correct with this explanation?
Is there any best practice regarding such a situation? While this
example is
constructed, I’m trying to create a namespace hierarchy in which a class
on
top mediates several others that live further below the hiearchy, but
don’t
derive from it.
I’m open for all kinds of suggestions.
Thanks alot in advance!
Eric
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
iEYEARECAAYFAkwWzmkACgkQhS0drJ3goJJSTwCfZ8mJghOxUeiAyApkQFo7PoBA
aT0An0GGVaN2aUIHJo8eMrmra7jS/xsy
=uQ4K
-----END PGP SIGNATURE-----
On Mon, Jun 14, 2010 at 7:18 PM, Eric MSP Veith
[email protected] wrote:
I’m trying to understand the way Ruby resolves symbol names and how the
require statement fits in.
The code is executed in a linear fashion.
a.rb:
require ‘a/b’
At this point, the code in a/b.rb is read and evaluated. So, jump
down to there.
a/b.rb:
require ‘a’
module Foo
class Foo:
:B < Foo::A
This expects Foo::A to exist, but the way you have written you code,
with this being required before Foo::A is defined in the a.rb code, it
won’t exist yet.
def say
puts “Hello, World”
end
end
end
With the above code, I get a “missing symbol” error. Placing the “require
‘a/b’” statement within the Foo::A class remedies it.
This is because by that time Ruby is aware of the existence of the
Foo:A class, so your code in a/b.rb can execute.
Is there any best practice regarding such a situation? While this example is
constructed, I’m trying to create a namespace hierarchy in which a class on
top mediates several others that live further below the hiearchy, but don’t
derive from it.
Just move your require statements.
If a.rb is defining stuff needed by a/b.rb, but you want a require of
a.rb to also load a/b.rb, then put that require somewhere else. It
doesn’t have to be in the class definition. You can do that, but were
it me, I’d just put it along with any other similar require statements
at the end of the file, or at least after the class definition that
those files are depending on.
Kirk H.
Developer
Engine Y.
On Mon, Jun 14, 2010 at 9:18 PM, Eric MSP Veith
[email protected] wrote:
Am I correct with this explanation?
Yes
Is there any best practice regarding such a situation? While this example is
constructed, I’m trying to create a namespace hierarchy in which a class on
top mediates several others that live further below the hiearchy, but don’t
derive from it.
I’m open for all kinds of suggestions.
Have a look at the Module#autoload, and Kernel#autoload methods
These can be a useful ‘sword’ when trying to manage requires manually
becomes a bit of a gordian knot.
–
Rick DeNatale
Blog: http://talklikeaduck.denhaven2.com/
Github: rubyredrick (Rick DeNatale) · GitHub
Twitter: @RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale
On Jun 15, 7:25 am, Rick DeNatale [email protected] wrote:
Have a look at the Module#autoload, and Kernel#autoload methods
These can be a useful ‘sword’ when trying to manage requires manually
becomes a bit of a gordian knot.
Yea, well, except for the fact that they are broken.
http://groups.google.com/group/ruby-talk-google/browse_thread/thread/f981e153fb3fc032/7077b6fe2b483092
On Tue, Jun 15, 2010 at 12:25 PM, Eric MSP Veith
[email protected] wrote:
so there’s no actual best practice regaring require() placement?
The best practice is to put it where it makes sense to put it, bearing
in mind you might have to read your code again in two years, or
someone else might have to read your code.
The convention is to put requires at the top of the file because it’s
immediately obvious what other libraries the code within the file
depends on.
But, obviously, you are trying to structure your code and your files
in a way that breaks that convention. So, either write your code
differently, structure your files differently, or move your requires.
If you move your requires, I’d put them outside of the class bodies
and method bodies, but as close to the relevant code as is reasonable.
You might also consider a comment or note someplace explaining why you
are doing things differently.
Kirk H.
Developer
Engine Y.
Kirk,
On Tuesday 15 June 2010, Kirk H. wrote:
Just move your require statements.
[…]
I’d just put it along with any other similar require statements
at the end of the file, or at least after the class definition that
those files are depending on.
so there’s no actual best practice regaring require() placement?
Eric
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Rick,
Intransition,
thanks for your answers!
On Tuesday 15 June 2010, Rick DeNatale [email protected] wrote:
Now I’m not quite sure why. I know that require() is a statement like
puts in regards of its execution time, i.e. there’s no special
treatment in some parse/compile/whatever phase before the actual
execution begins. As such, it seems logic that I get the missing symbol
error with the original code: Foo::A is not defined when the derivation
is made, and as such, putting require ‘a/b’ some lines later helps.
Am I correct with this explanation?
Yes
Ok, that’s a start. 
I haven’t read a lot of Ruby code so far, but from what I’ve looked at,
I
could see that require() typically goes at the top of the file. Seems to
be
some sort of (unwritten?) coding style guideline to me. I’m always
hestitant
to write code that at seems to be outside of the best practices pathway.
So
the obvious question is: Am I right with the assumption, that issuing a
require statement somewhere within the class or method is not quite a
good
style? (For a similar reason I’d like to avoid the autoloader, too,
besides
the problems it has.)
If so, I’m quite obviously creating a flawed design. What’s the
recommendation in this case?
TIA!
Eric
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
iEYEARECAAYFAkwXkVUACgkQhS0drJ3goJLapQCeMUgjoqulj4KdqX3gTrQEQAOK
1ukAn0017I/xUy75x8o71C9mrfl+JV70
=2tvl
-----END PGP SIGNATURE-----