Help repost to Ruby Dev -- 2 improvements to Ruby Magic

Discussion in 'Ruby' started by Sunny Hirai, Jun 6, 2007.

  1. Sunny Hirai

    Sunny Hirai Guest

    This is a proposed solution to simplify magic in Ruby.

    I'd appreciate it if somebody who has post access to 'Ruby-core' or
    'Ruby-dev' could post this message there. Thank you in advance. If you
    get to read this Matz, thank you for bringing about such an excellent
    language.

    -----

    I'm building a framework that has similarities to Ruby on Rails and Merb
    but targets the creation of website building software.

    In writing this software, one of the problems when reading other
    people's code to get ideas is that it is difficult to find the magic
    methods. Of course, there are several types of magic but I'd like to
    propose solutions to help eliminate the confusion that two common types
    of magic cause.

    1. Precede methods that are meant to be automagically called by 'on_'

    Here are a few examples for the Ruby language:

    * on_method_missing
    * on_initialize

    I consider them magic because they do something automatically and there
    is no direct call to either the 'method_missing' or 'initialize' method.

    And for adding methods that are automagically called to a class:

    * on_process
    * on_before_read
    * on_after_read
    * on_before_create
    * on_after_create

    When starting Ruby, it was difficult to know what the magic methods were
    and typically they were the last things to be mentioned in documentation
    (with the exception of initialize). They are second nature now but this
    naming convention makes it obvious that a method is a magic call making
    it simpler to learn the language for beginners. You just need to teach
    that 'on_' means this method is called automagically in some way and
    from there you look up what the 'on_whatever' call does.

    Also, consider the readability in the context of a lot of other methods.

    old way:
    * initialize
    * new
    * create
    * edit
    * post
    * validate
    * method_missing

    new way:
    * on_initialize
    * new
    * create
    * edit
    * post
    * on_validate
    * on_method_missing

    In the second of the two lists above, it is obvious which methods get
    executed automatically. For example, you may have known 'initialize' and
    'method_missing' were, but there was probably no indication that
    'validate' was called automatically. This is great for experienced users
    trying to quickly understand a class, but it is especially good for new
    users because they know that on_method_missing and on_initialize are
    magically called methods, and that on_validate is special in some way.

    One problem I had with reading through other source code was that it was
    difficult for me to tell where the entry points (magic methods) for the
    classes were without reading the RDoc. Locating the magic methods is
    time consuming, because you have to go through every method in the
    class. For example, Mongrel needs you to instantiate a handler class and
    then it calls 'process' when the handler needs to be executing. But
    reading the method names doesn't help you without first knowing that the
    method 'process' is the entry point. If the Ruby standard was to start
    with 'on_' and the method was named 'on_process', you could find the
    entry point either almost immediately, or at least reduce your search to
    a small handful of magic 'on_' methods.

    It was also difficult to find where magic methods were called from. This
    would be obvious if it was named on_before_read. This would allow for
    simple searching for the string 'on_'. I know its not foolproof
    searching, (e.g. may match 'json_read' though you can get around this
    with a regex as well) but it makes our job a little easier.

    2. Methods that are configuration should be preceded by 'has_'

    I love Rails configuration but it is hard to find what framework code is
    configuration without first learning the entirety of the framework. The
    rails convention (to use no brackets for configuration) helps when
    reading code but only when you read/write code that uses the framework.
    It doesn't help when trying to read/write the framework itself.

    Consider these methods in a class:

    * attr_reader
    * has_many
    * belongs_to
    * initialize
    * helper
    * prepare_stuff
    * before_create
    * after_read

    This is typically how classes read in Ruby.

    Now what about we rewrite this with our conventions

    * has_attr_reader (or has_reader)
    * has_children
    * has_parent
    * on_initialize
    * helper
    * prepare_stuff
    * on_before_create
    * on_after_read

    It is clear now which methods are automagically called, which ones are
    configuration and which ones are POMs (Plain Old Methods). In fact, this
    would probably help us organize our code at the subconscious level too.
    Because I want to reorder my methods now to look nicer, though there is
    no requirement that I do (I know in some cases it is better to have the
    magic calls closer to related calls):

    * has_attr_reader
    * has_children
    * has_parent
    * on_initialize
    * on_before_create
    * on_after_read
    * helper
    * prepare_stuff

    One thing you may be thinking about with the 'has_' convention is this:

    Will 'has_' work for every type of configuration? The answer is, I think
    so. I went through a book on Rails (I think I own every Ruby and Rails
    book published including some online ones) to see if every instance of
    configuration could be rewritten with a 'has_'. I considered different
    prefixes but found that 'has_' could be used in every case that I came
    across. In some cases, you had to be creative, but in no case was the
    name bad. In fact, I personally found that many of the names were
    better.

    Another benefit of standardizing on 'has_' is that it makes all
    configuration method names consistent. For example, 'attr_reader' is a
    noun, 'has_many' is, well, some other part of the English language.
    Having consistency helps us better understand what configuration does
    which is it describes some aspect of a class. For this use, 'has_' is a
    pretty good prefix.

    Finally, you may be concerned about my 'opinion' making its way into the
    language.

    Do the 'on_' and 'has_' changes really need to be made in the Ruby
    language itself? Isn't Mr. Hirai just trying to force me to program the
    way he programs? Why doesn't he just use it for himself? Well the answer
    is that I think it is important to have it in the Ruby language just
    like the convention for '?' and '!' on method name endings is used in
    the Ruby language. Nothing stops anybody from using the punctuation in
    other ways, but the convention in the base language has helped to make
    it work properly with all code. For example, if '!' was used for
    exciting methods, the value of the '!' would non-existent. It would just
    be another character in variable names.

    I know this sounds funny but try imagining that all automagic calls
    start with 'on_' and 'has_'. Think of how much easier it would be to
    read code that involved callbacks and meta programming. If you are
    having trouble picturing the difference semantics make, think of how
    much more difficult life would be if Ruby did NOT have '!' and '?' for
    method names. In fact, that simple punctuation has solved many naming
    conflicts.

    Well, that's it for now, but I'd be happy to discuss this more. This is
    a convention that I've already adapted for use in our web framework and
    it works. I'm also considering writing a new database abstraction
    library like ActiveRecord (but multi-threaded, connection pooling,
    multi-datasource, split-datasource for read/write, etc.) and would use
    it there..

    Again, if somebody has post access (or know somebody that does), I'd
    appreciate getting this in front of Matz and other contributors to the
    Ruby language.

    Sunny Hirai
    CEO, MeZine Inc.

    --
    Posted via http://www.ruby-forum.com/.
    Sunny Hirai, Jun 6, 2007
    #1
    1. Advertising

  2. Sunny Hirai

    Alex Young Guest

    Sunny Hirai wrote:
    > This is a proposed solution to simplify magic in Ruby.
    >
    > I'd appreciate it if somebody who has post access to 'Ruby-core' or
    > 'Ruby-dev' could post this message there. Thank you in advance. If you
    > get to read this Matz, thank you for bringing about such an excellent
    > language.

    <snip on_ and has_ proposal>

    I quite like this. I often feel that there's not quite enough
    consistency in method naming. It's more a problem in the stdlib than in
    core, though. The great thing about this specific proposal is that it's
    completely (I think) implementable with aliases, so it needn't break
    anything.

    --
    Alex
    Alex Young, Jun 6, 2007
    #2
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ron Peterson

    /dev/urandom vs. /dev/random

    Ron Peterson, Jan 7, 2005, in forum: C Programming
    Replies:
    21
    Views:
    1,508
    Keith Thompson
    Jan 13, 2005
  2. AC
    Replies:
    0
    Views:
    151
  3. Guest
    Replies:
    2
    Views:
    141
    Bob Barrows [MVP]
    Sep 18, 2005
  4. Replies:
    6
    Views:
    97
    Dave Thomas
    Apr 29, 2007
  5. Giles Bowkett
    Replies:
    9
    Views:
    395
    Giles Bowkett
    Dec 17, 2007
Loading...

Share This Page