SitePoint Sponsor

User Tag List

Page 1 of 2 12 LastLast
Results 1 to 25 of 48
  1. #1
    SitePoint Guru
    Join Date
    Aug 2005
    Posts
    986
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Learn Ruby on Rails: the Ultimate Beginner's Guide

    Notice: This is a discussion thread for comments about the SitePoint article, Learn Ruby on Rails: the Ultimate Beginner's Guide.
    __________

    I hope you haven't printed too many of these ;-).

    & I'm sorry if this is not correct; I'm too lazy to test it ;-).

    The example code contains an error.

    Code:
    class Car
      @mileage = 0       # instance variable 
      ...
    end
    The second line is misleading. It *is* an instance variable, but not an instance instance variable, it's a class instance variable: the instance variable of the Car object, not a Car instance. So there are *two* distinct variables in the example: the class' instance variable and the instances instance variable (which will be created in the setter method). This is a pretty fundamental thing: I think you do not understand Ruby's object model :(. Ruby is not Java: classes are objects and you initialize instance variables in instance methods (initialize() for example) and not in the class. I hope you explain attribute_accessor soon; that may have prevented this kind of error in the rest of the book.

  2. #2
    SitePoint Guru Skyblaze's Avatar
    Join Date
    Jul 2005
    Location
    Italy
    Posts
    734
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    i don't understand a single word you said. In the book (in the ruby tutorial initial part) it doesn't speak about your "instance instance variable". What is that? It is just a mess.

  3. #3
    ☆★☆★ 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 Skyblaze View Post
    i don't understand a single word you said. In the book (in the ruby tutorial initial part) it doesn't speak about your "instance instance variable". What is that? It is just a mess.
    Think of a it as a variable that's available to all members of the same class.

    This excerpt from the Programming Ruby book explains it pretty well: http://www.rubycentral.com/book/tut_classes.html#S3

  4. #4
    SitePoint Guru Skyblaze's Avatar
    Join Date
    Jul 2005
    Location
    Italy
    Posts
    734
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    i only see (as in the sitepoint ruby book) class variables, class methods, instance variables and instance methods

  5. #5
    SitePoint Guru silver trophy Luke Redpath's Avatar
    Join Date
    Mar 2003
    Location
    London
    Posts
    794
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yes, what Fenrir was trying to explain is that a class is also an object (of type Class) and as such a class can also have instance variables:

    Code:
    class Foo
      @bar = 'hello' # this is an instance variable of the Foo class itself (which is also an object)
    
      def initialize
        @bar = 'hello' # this is an instance variable for all instances of the Foo class
      end
    end
    Here's another way of looking at it. When you do class Foo; end it is really just syntatic sugar for creating a new instance of a Class object and assigning it to a constant. So:

    Code:
    # this:
    class Foo
    end
    
    # is the same as this:
    Foo = Class.new

  6. #6
    SitePoint Guru
    Join Date
    Aug 2005
    Posts
    986
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yes it is quite simple actually once you understand it ;-). The difference between instance variables and class variables is in the scoping rules (where you can access the variable). If you set an instance variable of a particular object you can only access it from inside the object:

    Code:
    class Foo
      def set_the_variable(value)
        @the_variable =  value
      end
    
      def print_the_variable
        print @the_variable
      end
    end
    Every instance of Foo has a distinct version of @the_variable:

    Code:
    foo1 = Foo.new
    foo1.set_the_variable("foo1's variable")
    
    foo2 = Foo.new
    foo2.set_the_variable("foo2's variable")
    
    foo1.print_the_variable # "foo1's variable"
    foo2.print_the_variable # "foo2's variable"
    This is what I called "instance instance variables".

    A class variable is different: there is only one variable for all objects:

    Code:
    class Foo
      def set_the_variable(value)
        @@the_variable =  value
      end
    
      def print_the_variable
        print @@the_variable
      end
    end
    
    foo1 = Foo.new
    foo1.set_the_variable("foo1's variable")
    
    foo2 = Foo.new
    foo2.set_the_variable("foo2's variable") # this one overwrites foo1's variable too
    
    foo1.print_the_variable # "foo2's variable" !!!
    foo2.print_the_variable # "foo2's variable"
    You can additionally access class variables in class methods:

    Code:
    class Foo
       # ... same as before ...
    
      def self.print_the_variable_from_the_class
         print @@the_variable
      end
    end
    
    foo1 = Foo.new
    foo1.set_the_variable("Hi!")
    
    Foo.print_the_variable_from_the_class # "Hi!"
    You can access class variables in the class and in the instances. You can access instance variables only in the instance.

    Because classes are objects they can have instance variables too. You cannot access these variables in the instances of the class (foo1 and foo2) -- only from the class itself.

    Code:
    class Bar
      @the_variable = "Hi!"
    
      def print_the_variable # note: this is an instance method
         print @the_variable  # this won't work because this instance variable doesn't exist: it belongs to the class
      end
    
      def self.print_the_variable # note: this is a class method
        print @the_variable  # this will work
      end
    end
    This is what I called "class instance variables": instance variables of a Class object (Bar in this case).

  7. #7
    ☆★☆★ silver trophy vgarcia's Avatar
    Join Date
    Jan 2002
    Location
    in transition
    Posts
    21,236
    Mentioned
    1 Post(s)
    Tagged
    1 Thread(s)
    Nice writeup fenrir

  8. #8
    SitePoint Guru Skyblaze's Avatar
    Join Date
    Jul 2005
    Location
    Italy
    Posts
    734
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    ok now i hope it is more clear ....let me do some explanation and tell me if i'm wrong:

    There are 3 types of variables in a class:
    1) Instances instance variable (and they are prefixed with a @ and ONLY declared in an instance method and can be accessed only from a particular instance of a class at a time);
    2) Class variables (they are prefixed with a @@ and declared in instance methods and class methods and are available for all the instances of the class);
    3) class instance variables ( they are prefixed with a @ and only declared outside any methods of that class).

  9. #9
    SitePoint Guru
    Join Date
    Aug 2005
    Posts
    986
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Correct From Ruby's point of view types 1 and 3 are the same: they're just instance variables. Ruby makes no distinction between classes and objects (classes are objects) in this respect.

  10. #10
    SitePoint Guru Skyblaze's Avatar
    Join Date
    Jul 2005
    Location
    Italy
    Posts
    734
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Fenrir2 View Post
    Correct From Ruby's point of view types 1 and 3 are the same: they're just instance variables. Ruby makes no distinction between classes and objects (classes are objects) in this respect.
    ok but can i declare an instances instance variable outside an instance method in a class?

  11. #11
    SitePoint Guru
    Join Date
    Aug 2005
    Posts
    986
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    No you cannot. (or: I don't know how). Most instance variables are defined in the constructor, which is an instance method.

    Edit: well, you can do this with instance_variable_set:

    Code:
    irb(main):001:0> class Foo
    irb(main):002:1> end
    => nil
    irb(main):003:0> f = Foo.new
    => #<Foo:0x282da3c>
    irb(main):004:0> f.instance_variable_set('@x', 4)
    => 4
    irb(main):005:0> f.instance_variable_get('@x')
    => 4
    But instance_variable_set is an instance method ;-).

  12. #12
    SitePoint Guru Skyblaze's Avatar
    Join Date
    Jul 2005
    Location
    Italy
    Posts
    734
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    ok, and class variables in a class outside any method?

  13. #13
    SitePoint Guru
    Join Date
    Aug 2005
    Posts
    986
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You can access class variables in the class declaration, class methods AND in the instance methods.

  14. #14
    SitePoint Guru Skyblaze's Avatar
    Join Date
    Jul 2005
    Location
    Italy
    Posts
    734
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    so the error declared at the beggining of the post is real? Is it really an error or bad practise to initialize instance variables outside instance methods? If it is than the author of the book has made a very big mistake.....i hope typo mistake

  15. #15
    SitePoint Guru
    Join Date
    Aug 2005
    Posts
    986
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well the code still works but it creates a separate variable.

    Code:
    class Foo
      @something = 4  # this variable
      
      def somemethod()
        @something = 3  # is totally distinct from this variable
      end
    end
    
    # much like
    
    something = 4  # this variable
    
    def yyy()
      something = 3  # isn't the same variable as this one, they just have the same name.
    end
    
    # so if we call
    
    yyy()
    
    # something still contains 4
    This will not do any harm but it is a mistake. And I think it is misleading and confusing.

    If you do this:

    Code:
    class Foo
      @something = 4  # this line sets the class instance variable @something
      
      def get_something
        return @something # this returns the instance instance variable @something
      end
    end
    
    a_foo = Foo.new
    a_foo.get_something # returns nil (the NULL value of Ruby) instead of 4, as most people would expect after reading the code sample of the book

  16. #16
    SitePoint Guru Skyblaze's Avatar
    Join Date
    Jul 2005
    Location
    Italy
    Posts
    734
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    perfectly clear

    so the book example is valid anyway 'cause it is only a variable initialization to the value 0......and the instance instance variable in the instance method is assigned a value taken from the method parameter so it is irrilevant the real class instance variable initialization :P

    is it right?

  17. #17
    SitePoint Guru
    Join Date
    Aug 2005
    Posts
    986
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    That's right .

  18. #18
    SitePoint Guru mattymcg's Avatar
    Join Date
    Oct 2005
    Location
    Melbourne, Australia
    Posts
    574
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Post

    Good spot Fenrir2, and an interesting discussion.

    We made a decision not to include a discussion about class-level and object-level instance variables in an introductory chapter, for the sake of simplicity (and considering that class-level instance variables are rarely required when working with Rails).

    However you are correct in that instance variables in Ruby do not need declaring, so the line initializing @mileage to 0, while not strictly incorrect, is indeed redundant and misleading. I've updated the article and the book's errata page to hopefully clarify this.
    Last edited by mattymcg; Feb 7, 2007 at 22:44. Reason: Corrected misspelling of Fenrir2's name!
    I design beautiful, usable interfaces. Oh, and I wrote a kids' book.
    Follow me on Twitter.
    Read my blog.
    Buy my book, Charlie Weatherburn and the Flying Machine.

  19. #19
    SitePoint Guru Skyblaze's Avatar
    Join Date
    Jul 2005
    Location
    Italy
    Posts
    734
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by mattymcg View Post
    Good spot Fenrir2, and an interesting discussion.

    We made a decision not to include a discussion about class-level and object-level instance variables in an introductory chapter, for the sake of simplicity (and considering that class-level instance variables are rarely required when working with Rails).

    However you are correct in that instance variables in Ruby do not need declaring, so the line initializing @mileage to 0, while not strictly incorrect, is indeed redundant and misleading. I've updated the article and the book's errata page to hopefully clarify this.
    Ok but remember that your instance variable initalization(that not need to be initializated) is in fact a class instance initialization so you have also to move that initialization inside the instance method to do that a correct "instance variable initalization". right?

  20. #20
    SitePoint Guru Skyblaze's Avatar
    Join Date
    Jul 2005
    Location
    Italy
    Posts
    734
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    ....then i found in the book sometimes code statements that are not correctcly explained. i.e. i find a name followed by a hash. What is it? a method with a parameter without parenthesis or what?

    for example...i found this:

    redirect_to :action => 'index'


    it doesn't say anything about that "redirect_to" is a method and if the part that begginings with ":action..." is the paramether to the method without parenthesis.....or it is just a typo error?
    Last edited by Skyblaze; Feb 8, 2007 at 04:10.

  21. #21
    SitePoint Guru mattymcg's Avatar
    Join Date
    Oct 2005
    Location
    Melbourne, Australia
    Posts
    574
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    @Skyblaze:

    1) Yes, if you want to move @mileage = 0 into the initialize method you could do that, and that would correctly give the object-level instance variable an initial value of zero. However each time this variable is referenced in the chapter, it is initialized with a value first, so for the errata page I chose to remove its initialization altogether.

    2) Re: "A name followed by a hash", could you be more specific? In Ruby, a hash (#) is used to indicate a comment -- this is explained on page 60.

    3) The redirect_to method redirects the user to the controller action that you pass to it in the form of a symbol. The syntax redirect_to :action => 'my_action' and redirect_to(:action => 'my_action') are identical. The => operator assigns a value to an argument that is passed to a method (in Ruby, parentheses are often optional, as described in Chapter 3). Use of this operator in this manner is introduced in Chapter 5 (page 129).

    Hope that helps.

    Matt
    Last edited by mattymcg; Feb 8, 2007 at 16:50.
    I design beautiful, usable interfaces. Oh, and I wrote a kids' book.
    Follow me on Twitter.
    Read my blog.
    Buy my book, Charlie Weatherburn and the Flying Machine.

  22. #22
    SitePoint Guru Skyblaze's Avatar
    Join Date
    Jul 2005
    Location
    Italy
    Posts
    734
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by mattymcg View Post
    @Skyblaze:

    1) Yes, if you want to move @mileage = 0 into the initialize method you could do that, and that would correctly give the object-level instance variable an initial value of zero. However each time this vairiable is referenced in the chapter, it is initialized with a value first, so for the errata page I chose to remove its initialization altogether.

    2) Re: "A name followed by a hash", could you be more specific? In Ruby, a hash (#) is used to indicate a comment -- this is explained on page 60.

    3) The redirect_to method redirects the user to the controller action that you pass to it in the form of a symbol. The syntax redirect_to :action => 'my_action' and redirect_to(:action => 'my_action') are identical. The => operator assigns a value to an argument that is passed to a method (in Ruby, parentheses are often optional, as described in Chapter 3). Use of this operator in this manner is introduced in Chapter 5 (page 129).

    Hope that helps.

    Matt
    1) ok
    2) a hash i mean an Hash object
    3) ok you have explained what that method doeas but that explanation is not in the book anyway.

    i don't know....i really don't like very much the book....it doesn't explain very well all the things..

  23. #23
    SitePoint Guru mattymcg's Avatar
    Join Date
    Oct 2005
    Location
    Melbourne, Australia
    Posts
    574
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Skyblaze View Post
    i don't know....i really don't like very much the book....it doesn't explain very well all the things..
    Sorry to hear that - other customers have said the opposite, but of course everyone's different and thanks for letting us know. I'll definitely pass your feedback on to the author; we'll try to address some of the areas that you found confusing in future editions. And hopefully as you progress through the rest of the book you'll find value in what it teaches...
    I design beautiful, usable interfaces. Oh, and I wrote a kids' book.
    Follow me on Twitter.
    Read my blog.
    Buy my book, Charlie Weatherburn and the Flying Machine.

  24. #24
    SitePoint Guru
    Join Date
    Aug 2005
    Posts
    986
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This is a verbose version:

    redirect_to({:action => 'index'});

    We don't need parentheses and semicolons in Ruby:

    redirect_to {:action => 'index'}

    If you pass a hash in the last parameter you don't have to write the accolades:

    redirect_to :action => 'index'

  25. #25
    SitePoint Guru Skyblaze's Avatar
    Join Date
    Jul 2005
    Location
    Italy
    Posts
    734
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Fenrir2 View Post
    This is a verbose version:

    redirect_to({:action => 'index'});

    We don't need parentheses and semicolons in Ruby:

    redirect_to {:action => 'index'}

    If you pass a hash in the last parameter you don't have to write the accolades:

    redirect_to :action => 'index'
    ok so an important explanation like that must not left in a book like this.
    i hope you will release an update pdf for those who purchased the pdf edition
    Last edited by Skyblaze; Feb 11, 2007 at 06:16.


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
  •