SitePoint Sponsor

User Tag List

Results 1 to 25 of 25
  1. #1
    SitePoint Enthusiast
    Join Date
    Jan 2004
    Location
    Manchester
    Posts
    32
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    OO Question: No abstract classes or interfaces a good thing?

    I'm looking at moving from PHP5 to Ruby, and I've recently had another look at the ruby-lang.org site. There's a section on how Ruby compares to PHP(5).

    One of the differences is states is that "there’s no abstract classes or interfaces". I'm no OO guru, but wouldn't that be cause for concern? I've been using frameworks and developing in OO now for about 5 years and while I use abstract classes and interfaces sparringly, I've found them useful - especially when developing a custom Database abstraction layer.

    To those of you who have come from another OO language to Ruby, and use Ruby outside of the RoR camp, I ask: do you miss not having abstract classes and interfaces? Is your life now easier without them? What are your thoughts on the matter?

  2. #2
    ☆★☆★ silver trophy vgarcia's Avatar
    Join Date
    Jan 2002
    Location
    in transition
    Posts
    21,236
    Mentioned
    1 Post(s)
    Tagged
    1 Thread(s)
    Abstract classes aren't really a big deal when you can change the details of any class/method whenever you want. Let's say you wanted to rewrite how Ruby does uppercasing of strings:
    Code:
    # ...some unrelated code up here...
    
    class String
      def upcase
        #do what you want here
      end
    end
    
    "Foo-Bar".upcase #will use your upcase method

  3. #3
    SitePoint Guru
    Join Date
    Aug 2005
    Posts
    986
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You could use a normal class every time you use an abstract class?

  4. #4
    SitePoint Enthusiast
    Join Date
    Jan 2004
    Location
    Manchester
    Posts
    32
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If you can manipulate an object/class at any point, doesn't that make it more important that you can set some rules using an interface or overwrite abstract methods/classes to ensure that you're extending your classes in the right way?

  5. #5
    ☆★☆★ silver trophy vgarcia's Avatar
    Join Date
    Jan 2002
    Location
    in transition
    Posts
    21,236
    Mentioned
    1 Post(s)
    Tagged
    1 Thread(s)
    Quote Originally Posted by neobuddah
    If you can manipulate an object/class at any point, doesn't that make it more important that you can set some rules using an interface or overwrite abstract methods/classes to ensure that you're extending your classes in the right way?
    Or you can just build the class and let people use it as-is or in the way they want to.

  6. #6
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Unlike classes or objects, abstracts and interfaces are not something that exists in objective reality. They are only "scaffolding" needed to support c++/java static typing system. Since ruby doesn't have static types, there's no need of them.

  7. #7
    SitePoint Enthusiast
    Join Date
    Jan 2004
    Location
    Manchester
    Posts
    32
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by stereofrog
    Unlike classes or objects, abstracts and interfaces are not something that exists in objective reality. They are only "scaffolding" needed to support c++/java static typing system. Since ruby doesn't have static types, there's no need of them.
    OK, but isn't that thinking in Ruby terms? How, in Ruby, would you ensure a set of objects to conform to a specific set of methods?

    For example, how would I ensure that any developer who creates an extension to my "SendMessage" class makes available the methods I outlined (addRecipient, setBody, sendMessage)? How could I ensure that I don't miss overwriting important methods (such as sendMessage) when extending my "SendMessage" class with "SendHTMLEMail" and "SendTextEMail"? How would I ensure that nobody modifies at run-time the common methods these child classes expect available in the parent (such as parent::getRecipients)?

  8. #8
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by neobuddah
    OK, but isn't that thinking in Ruby terms?
    Of course it is. We are in the ruby forum after all.

    How, in Ruby, would you ensure a set of objects to conform to a specific set of methods?
    1. you document it
    2. you unittest it
    3. people who extend your class, document and unittest their changes.

    The point is you cannot "ensure" anything about your program without running it.

    This static vs dynamic (aka interfaces vs ducks, aka java vs ruby) debate has a long long history... I hope you excuse me for not trying to retell the whole story again. Let me just refer you to the Bruce Eckel's article that summarizes both points.

  9. #9
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by neobuddah
    How, in Ruby, would you ensure a set of objects to conform to a specific set of methods?
    You can simply test for the existence of a given method before you call it, changing your concern from "is this object the right type?" to "can this object do what I want it to?", which is ultimately what you're concerned about. Advocates of static typing often claim that catching type errors at compile time is better than at run time, but in many people's experience this isn't an issue at all, and even if it were, it can be properly mitigated via the use of unit testing. Also note that there may be other ways of achieving your desired effect using some existing Ruby functionality, such as mixins.

  10. #10
    SitePoint Enthusiast
    Join Date
    Jan 2004
    Location
    Manchester
    Posts
    32
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I see... but what I'm concerned about is providing a "scaffold" which the other developers in my team must follow. Its all well and good testing whether the parent has a method which you want to use when you're coding the child class, but I'm developing the parent, and need to be able to create an abstract class and say "these are the methods you must overwrite, failure to do so will cause an error". Is this not possible in Ruby?

  11. #11
    SitePoint Guru
    Join Date
    Aug 2005
    Posts
    986
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    It's possible through stupid hacks, but you shouldn't use them. Let the users of your class take care of themselves. Your parent should provide utilities for the children. How (and if) they use them is their business.

  12. #12
    ☆★☆★ silver trophy vgarcia's Avatar
    Join Date
    Jan 2002
    Location
    in transition
    Posts
    21,236
    Mentioned
    1 Post(s)
    Tagged
    1 Thread(s)
    Quote Originally Posted by neobuddah
    I see... but what I'm concerned about is providing a "scaffold" which the other developers in my team must follow. Its all well and good testing whether the parent has a method which you want to use when you're coding the child class, but I'm developing the parent, and need to be able to create an abstract class and say "these are the methods you must overwrite, failure to do so will cause an error". Is this not possible in Ruby?
    Why not pass them the spec and let them code it, instead of writing code twice for use once?

    Violating your interface or your specs would mean that the end product does not work. That alone should keep conformance to standards high.

  13. #13
    SitePoint Zealot bronze trophy
    Join Date
    Jun 2004
    Location
    Stockholm, Sweden
    Posts
    148
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ruby is a language for people who don't require the language/compiler/etc. to hold their hand for them.

    Yes, your fellow developers might **** up the implementation of child classes. But then you have bigger problems than the fact that your language of choice doesn't prevent them from ****ing up.
    If there is a way to overcome the suffering, there is no need to worry; if there is no way to overcome the suffering, there is no point to worry.
    - Shantideva

  14. #14
    SitePoint Enthusiast
    Join Date
    Oct 2006
    Posts
    85
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by stereofrog
    Unlike classes or objects, abstracts and interfaces are not something that exists in objective reality.
    Sure, abstract classes exist in reality. Take for instance animal. No creature is "an animal" and that's it.

  15. #15
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well, following this logic, there is also no mammals (because every mammal is a cat, or a dog, or a cow) and no humans (because they're Tom, or Bob, or Sally). "Animals" is what we call "parent class", not an "abstract" class.

  16. #16
    SitePoint Enthusiast
    Join Date
    Oct 2006
    Posts
    85
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    well it would be abstract, because it can't be a concrete object

    no matter what you call it, it's still an abstract class.

  17. #17
    SitePoint Zealot
    Join Date
    Jul 2004
    Location
    Oklahoma
    Posts
    119
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by neobuddah
    I see... but what I'm concerned about is providing a "scaffold" which the other developers in my team must follow. Its all well and good testing whether the parent has a method which you want to use when you're coding the child class, but I'm developing the parent, and need to be able to create an abstract class and say "these are the methods you must overwrite, failure to do so will cause an error". Is this not possible in Ruby?
    The best advice I can give you on starting down the Ruby path is not to figure out how X feature from Y language works in Ruby. If you're used to C++/Java/C# static typing, and class structures, then you have a lot to "re-learn". The best example of this I can give, is as simple as the way a method is dispatched in Ruby.

    In Ruby lets say I have the following code:
    Code:
    class A
       def some_method
         puts "hello world"
       end
    end
    
    b = A.new
    b.some_method
    What I have really done is

    Code:
    b= A.new
    b.send(:some_method)
    I've sent a message to the object stored in 'b'. This simple change in how methods are dispatched has immense effects on the language as a whole. It means private isn't really private, it makes interfaces difficult (due to the fact that I could actually change the structure of the interface class, how would that affect classes that are re-using the interface?)

    Ruby is a complex language, but you won't get the most out of it's abilities if you just try to re-implement Java/C++ in Ruby.

  18. #18
    SitePoint Enthusiast
    Join Date
    Jan 2004
    Location
    Manchester
    Posts
    32
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Sgarissta
    Ruby is a complex language, but you won't get the most out of it's abilities if you just try to re-implement Java/C++ in Ruby.
    This could be problemattic. Coming from a PHP background (I've never bothered with any C++/Java stuff), re-learning a lot of how Ruby handles OO is going to be difficult. Learning OO from books on patterns, then finding that those patterns can't be properly enforced in Ruby is going to be hard, especially when googling ruby seems to return way too much RoR for my liking.

    I'm considering putting Ruby down for the minute; it seems as though I'm going to have to make a large investment in time before I can simply make apps with it, as I've been able to do with XQuery, XSL, PHP, and other languages.

  19. #19
    SitePoint Zealot
    Join Date
    Jul 2004
    Location
    Oklahoma
    Posts
    119
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by neobuddah
    This could be problemattic. Coming from a PHP background (I've never bothered with any C++/Java stuff), re-learning a lot of how Ruby handles OO is going to be difficult. Learning OO from books on patterns, then finding that those patterns can't be properly enforced in Ruby is going to be hard, especially when googling ruby seems to return way too much RoR for my liking.
    It's not re-learning OO, it's just another addition to how OO can work. In fact most patterns translate fairly well, in fact many are already built into Ruby (Delegates, Enumerators, etc). There are others that don't translate as well. It's not because Ruby can't do those things, it's that it has solved the problem the pattern is trying to address in a different manner.

    I'd actually argue that after a couple of weeks with Ruby, you'll feel that it's a much more natural approach OO. It's far from difficult, it's just different. I HIGHLY recommend the Pickaxe book from http://www.pragprog.com, it's pretty much THE reference for how to write Ruby.

    I'm considering putting Ruby down for the minute; it seems as though I'm going to have to make a large investment in time before I can simply make apps with it, as I've been able to do with XQuery, XSL, PHP, and other languages.
    I'd actually say it's because you're diving in pretty deep, pretty fast. Instead of worrying about why Ruby doesn't have interfaces, work on some smaller, less complex components first. I know the temptation is to leap directly to the more complicated stuff, to get a feel for how your advanced knowledge of Technology X, translates to Technology Y, but when learning a new language, especially one as deep as Ruby, it's probably best to start on the simpler side. That said I've only been writing ruby with any regularity for less than a year, coming from a similar background to your own. Once you get the feel of it, you'll not want to go back to PHP again

    Good luck, and please feel free to ask any other questions you get as they come up.

  20. #20
    SitePoint Enthusiast
    Join Date
    Jan 2004
    Location
    Manchester
    Posts
    32
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Sgarissta
    It's not because Ruby can't do those things, it's that it has solved the problem the pattern is trying to address in a different manner.
    I see... nobody tells you these things when you pick up a new language... it can be difficult at times, until you find that one resource that makes everything click. http://dpawson.co.uk took me a while to find, but when it did XSL just popped into place in my head after flicking through some of the threads.
    Quote Originally Posted by Sgarissta
    I HIGHLY recommend the Pickaxe book from http://www.pragprog.com, it's pretty much THE reference for how to write Ruby.
    Thanks! Just what I need. I'm sick of walking into bookshops, going to the computer section, and seeing nothing but RoR books. I've got this on order now!
    Quote Originally Posted by Sgarissta
    I'd actually say it's because you're diving in pretty deep, pretty fast.
    Sounds just like me, that...
    Quote Originally Posted by Sgarissta
    Instead of worrying about why Ruby doesn't have interfaces, work on some smaller, less complex components first.
    I've got a task I've assigned myself to complete in Ruby. Would be simple in PHP, but I'm having difficulty knowing where to start in Ruby. I think its just because I'm thinking in PHP terms, and not in Ruby yet. Hopefully the above book will help.

    Thanks again for your response, you've been the best help yet.

  21. #21
    SitePoint Addict
    Join Date
    Mar 2004
    Location
    Grand Junction, CO
    Posts
    292
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I had the same idea as you when I first started using Ruby after several years of doing all my work in Java.

    What you're encountering is Ruby's duck-typing compared to Java/PHP's static typing.

    For example, in Java you may have
    Code:
    public void doSomething(Poppable p) {
      something = p.pop();
      // Do some other stuff
    }
    The interface is defined simply to help you and the compiler out at compile time.

    In Ruby, it'd look like

    Code:
    def do_something(p)
      p.pop
      # Do some other stuff
    end
    I'm not going to go into the arguments of static vs dynamic typing here, because they've been discussed ad nauseum.

    So the real reason you have interfaces is to catch errors at compile time. Abstract classes serve the same purpose, but of course can also provide some of the implementation, use inversion of control, etc.

    I remember reading somewhere in these posts, "How do I make sure that people implement the right methods?"
    Basically, you just tell them or let their code blow up. In Java when someone implements an interface but forgets the implement one of the methods, the compiler goes "Hey! You still have work to do!" In Ruby, it's the same thing, but it's the interpretter that does it at runtime instead. If you've written a library, and people pass their own objects into it, you just need to tell them what methods to implement. If they don't read it, they'll find out soon enough, just as if they had used an interface.

    One last thing I want to point out is the importance of testing in Ruby. In fact, you'll quickly find that TDD in the Ruby community is HUGE. The reason for that is pretty obvious once you go back up to my "or let the code blow up" comment. If you're writing your tests before your production code, the tests are the ones that blow up. Most people agree it's bad to release untested code. In statically-typed languages the compiler will find simple errors like that, so they don't show up in production. But in dynamic languages it's INSANE to release untested code because you don't know about those errors until it's actually running. That's why you'll see so many Ruby hackers use TDD all the time.

    Wow this got a lot longer than I anticipated. Hopefully I helped explain some stuff for you though. Finally, you asked if it makes things easier, and I can say 100% that it does for me. I much prefer duck-typing over interfaces. If some code calls a certain method, you just add it to your class. With interfaces, you'll have to implement all the methods, even if you're only using one method! In the end I think it all boils down to how you work. There are upsides and downsides to each of those approaches, and you have to consider them as only a portion of the upsides and downsides to the languages themselves.

  22. #22
    SitePoint Addict
    Join Date
    Mar 2004
    Location
    Grand Junction, CO
    Posts
    292
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Also, one thing I found very illuminating in regards to the Ruby approach was reading Design Patterns, after I had a basic understanding of Ruby. As you read it, you'll find that at least 1/3 of the patterns aren't necessary in Ruby - the problems they solve simply don't exist in Ruby! That's not to say that Ruby is better than Java, but rather that the different approach makes it easy and obvious to write certain types of code, without having to work around the language.

    For me, discovering that was a bit of an aha! moment. As I said though, it doesn't make Ruby better, it just illustrates some of the differences. I have no doubt that at some point in the future there will be a language that eliminates some workarounds in Ruby (though I don't know those are yet, only time will tell).

  23. #23
    SitePoint Member
    Join Date
    Nov 2006
    Posts
    7
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    However weird this may sound, I actually find it easier to understand Ruby after understanding the functional programming paradigm. Despite Ruby being totally OO, i didn't really appreciate/understand Ruby's power until i learn Lisp. Transacting from Javascript to Ruby is actually easier than moving from Java to Ruby due to Javascript's metaprogramming capabilities.

    I agree with pergesu. Once you start doing Ruby, you realize that your prized patterns are not longer needed.

  24. #24
    SitePoint Zealot
    Join Date
    Jul 2004
    Location
    Oklahoma
    Posts
    119
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by skruby
    However weird this may sound, I actually find it easier to understand Ruby after understanding the functional programming paradigm. Despite Ruby being totally OO, i didn't really appreciate/understand Ruby's power until i learn Lisp. Transacting from Javascript to Ruby is actually easier than moving from Java to Ruby due to Javascript's metaprogramming capabilities.
    While Ruby is definitely an OO language, it borrows a lot from functional programming as well. Closures, blocks, and in general it's meta programming remind a lot of people of functional languages they've worked in. That said it's missing a few things as well, optimized tail recursion, and if you're a Lisper, then macros definitely seem lacking. I love Ruby because it bridges a lot of the various programming "paradigms" but still gives plenty of room to just be Ruby.
    I agree with pergesu. Once you start doing Ruby, you realize that your prized patterns are not longer needed.
    Knowing the design patterns is great, it allows you to look at abstraction in a different way for sure. But Ruby being as dynamic as it is, it just doesn't have the same set of problems to solve as some of the other languages, it's great!

  25. #25
    SitePoint Evangelist
    Join Date
    Jan 2005
    Posts
    502
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by vgarcia View Post
    Or you can just build the class and let people use it as-is or in the way they want to.
    I like that quote


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •