Forum: Ruby Ixnay on the Amphibious Programming

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.
Trans (Guest)
on 2006-04-01 18:00
(Received via mailing list)
I have finally come to the conclusion that the non-localality of
instance variables, independent of attribute methods, is not good.
Under worse case scenarios, it can lead to amphibious programming --
class diving to find culprit IVs. What's the problem? On the surface,
it's that Rubyists treat instance variables as if they were local to
the class or module in which they are defined. And while we all know
they are not, consider how often you have seen documentation that lists
all of a classes/modules instance variables? Probably never, since we
can't look to RDoc for help. And since instance variables are
autoviviable, there's really no way for RDoc to even completely do so.
It's unfortunate. But what can we do? The fact is Ruby makes it seem
okay.

Now, maybe you're wondering what the problem is exactly, and, if it is
indeed such a problem, why hasn't it biten you before. Well, consider
the following.


  class Amphibian
    def initialize( amphibian_type )
      @type = amphibian_type
    end
    def amphibian_type ; @type ; end
    def hop
      puts "And the #{amphibian_type} hops!"
    end
  end

  class Toad < Amphibian
    attr_reader :type
    def initialize
      super( 'Toad' )
      @type = 'dry'
    end
    def hop
      puts "And the #{type} #{amphibian_type} hops!"
    end
  end

  class Frog < Amphibian
    attr_reader :type
    def initialize
      super( 'Frog' )
      @type = 'slimmy'
    end
    def hop
      puts "And the #{type} #{amphibian_type} hops!"
    end
  end

  Toad.new.hop
  Frog.new.hop

produces

  And the dry dry hops!
  And the slimmy slimmy hops!


These things should not be hopping! Obviously, we got the wrong hoppers
b/c our Frog and Toad programmer did not know our "aqua team"
programmer used the @type instance variable. And therein lies the clue
as to why this doesn't often "bite". Ruby has a convention of naming
attributes the same as its instance variables. A convention pushed by
the use of the convenience methods attr, attr_reader, attr_writer and
attr_accessor. So, more often then not #type gets @type and #type= sets
@type. This convention (combined with the simple fact that there are a
many words to choose from) greatly reduces the likelihood of instance
variable name clash.

I can imagein that someone might come along and claim this to actually
be feature. --easily sharing instance variables between classes and
subclasses, w/o generally having to worry about banging inot one
another thanks a ingenious convention. Yea, well while it usually
works, its not something with which a critical applications developer
tends to feel terribly comfortable, esspecially when deploying to a
live scenario. And, yes, I realize, some of you will point out
test-first development. Sure, that can help, but that's not a good
excuse. You can use that argument to justify goto and using only global
variables. In the end, it's not really a feature at all, and leads to
less stable code.
Randy K. (Guest)
on 2006-04-02 00:15
(Received via mailing list)
On Saturday 01 April 2006 08:58 am, Trans wrote:
> And since instance variables are autoviviable, there's really no way for
RDoc to even completely do so.

Can anybody explain (or point to an explanation) of autoviviable
variables?

Randy K.
Logan C. (Guest)
on 2006-04-02 00:30
(Received via mailing list)
On Apr 1, 2006, at 3:11 PM, Randy K. wrote:

> Can anybody explain (or point to an explanation) of autoviviable
> variables?

I think he means the fact that ivars don't throw name errors (or no
method errors) if they haven't been assigned to yet, they just become
nil by default.
Robert D. (Guest)
on 2006-04-02 00:33
(Received via mailing list)
On 4/1/06, Trans <removed_email_address@domain.invalid> wrote:
>
> I have finally come to the conclusion that the non-localality of
>
>
> Wow, let us see if I got what you mean.



class General





--
Deux choses sont infinies : l'univers et la bêtise humaine ; en ce qui
concerne l'univers, je n'en ai pas acquis la certitude absolue.

- Albert Einstein
Robert D. (Guest)
on 2006-04-02 00:58
(Received via mailing list)
My appologies to the list, there is a keyboard shortcut sending mails
without asking me, gotta find it. :(

Did not come up with the *reasonable* questions I thought I had on my
mind.
I hope there will be some interesting reponses, I am still *thinking*

....
Trans (Guest)
on 2006-04-02 01:59
(Received via mailing list)
> I think he means the fact that ivars don't throw name errors (or no
> method errors) if they haven't been assigned to yet, they just become
> nil by default.

That's right.

  class X
    def yelp!
      @yelpling
    end
  end

  X.new.yelp!   #=>  nil

Just invoking @yelping brings it into existence. You do not need to
assign it first, like you do local vars.

T.
This topic is locked and can not be replied to.