Forum: Ruby uninitialized stream (IOError)

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
9d4960f8319664f0f7896230eebace73?d=identicon&s=25 Glen Holcomb (Guest)
on 2009-07-16 17:58
(Received via mailing list)
So I'm getting an unexpected IOError in my code.

class ConfigStub < File
    def initialize(location)
        unless filename = location.gsub("/", "_")
            raise ArgumentError, INVALID_LOCATION_FORMAT
        end
        @stub = 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 = SanityChecker.new()
        @config_stub = ConfigStub.new(location)
        @directive = ["<Location #{location}>"]

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


When it goes to execute the @config_stub.each do |line| section I get
the
following error:

    in `each': uninitialized stream (IOError)


My Ruby version is as follows:

    ruby 1.9.1p129 (2009-05-12 revision 23412) [i686-linux]


What am I missing?

-Glen

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

-Greg Graffin (Bad Religion)
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (candlerb)
on 2009-07-16 21:19
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.
9d4960f8319664f0f7896230eebace73?d=identicon&s=25 Glen Holcomb (Guest)
on 2009-07-16 23:15
(Received via mailing list)
Thanks Brian.

On Thu, Jul 16, 2009 at 1:19 PM, Brian Candler <b.candler@pobox.com>
wrote:

>
>    @stub.read(*args)
> If you want to subclass File, then you'll need to ensure you call its
> careful (as I think you've already discovered)
>
> Regards,
>
> Brian.
> --
> Posted via http://www.ruby-forum.com/.
>
>


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

-Greg Graffin (Bad Religion)
This topic is locked and can not be replied to.