uninitialized stream (IOError)

G

Glen Holcomb

So I'm getting an unexpected IOError in my code.

class ConfigStub < File
def initialize(location)
unless filename =3D location.gsub("/", "_")
raise ArgumentError, INVALID_LOCATION_FORMAT
end
@stub =3D File.open(CONFIG_PATH + filename, "w+") # This might need=
to
be more sophisticated depending on the rule
end # initialize
end # ConfigStub class

class Directive
def initialize(location)
@sanity_checker =3D SanityChecker.new()
@config_stub =3D ConfigStub.new(location)
@directive =3D ["<Location #{location}>"]

@config_stub.each do |line|
@directive << line
end
end # initialize
 
B

Brian Candler

You're trying to mix subclassing and delegation.

That is: your object is a subclass of File, and therefore an instance of
ConfigStub *is* a File. However you are also opening another File and
storing it in the instance variable @stub, and therefore it *has* a File
as well.

Choose one or the other. In my experience, delegation is the most
flexible and understandable approach, and although it needs some setting
up it ends up being simplest in the long run.

You can delegate manually:

class ConfigStub
def initialize(location)
@stub = File.open(...)
end
def each(*args,&blk)
@stub.each(*args,&blk)
end
def read(*args)
@stub.read(*args)
end
... etc, and/or
def method_missing(*args,&blk)
@stub.__send__(*args,&blk)
end
end

or use a wrapped up version of this - check out SimpleDelegator in
delegate.rb in the standard library.

If you want to subclass File, then you'll need to ensure you call its
initialize method. Probably something like this (untested):

class ConfigStub < File
def initialize(location)
..
super(CONFIG_PATH + filename, "w+") # in the superclass
end
end

But subclassing core classes can get you tied up in knots if you're not
careful (as I think you've already discovered)

Regards,

Brian.
 
G

Glen Holcomb

Thanks Brian.

You're trying to mix subclassing and delegation.

That is: your object is a subclass of File, and therefore an instance of
ConfigStub *is* a File. However you are also opening another File and
storing it in the instance variable @stub, and therefore it *has* a File
as well.

Choose one or the other. In my experience, delegation is the most
flexible and understandable approach, and although it needs some setting
up it ends up being simplest in the long run.

You can delegate manually:

class ConfigStub
def initialize(location)
@stub =3D File.open(...)
end
def each(*args,&blk)
@stub.each(*args,&blk)
end
def read(*args)
@stub.read(*args)
end
... etc, and/or
def method_missing(*args,&blk)
@stub.__send__(*args,&blk)
end
end

or use a wrapped up version of this - check out SimpleDelegator in
delegate.rb in the standard library.

If you want to subclass File, then you'll need to ensure you call its
initialize method. Probably something like this (untested):

class ConfigStub < File
def initialize(location)
..
super(CONFIG_PATH + filename, "w+") # in the superclass
end
end

But subclassing core classes can get you tied up in knots if you're not
careful (as I think you've already discovered)

Regards,

Brian.


--=20
"Hey brother Christian with your high and mighty errand, Your actions speak
so loud, I can=92t hear a word you=92re saying."

-Greg Graffin (Bad Religion)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top