Instance Variables in Ruby

Source: Internet
Author: User






Dogs has many shared characteristics, like the abilities to wag their tails and drink water from a bowl, but they also ha ve information about them it is variable,



Like their breed or their name.



Similarly, when designing an application, your users would have common traits, like the ability-log in and out, but some Information'll be variable,



Like a username or email address. Let's start by setting up a newUserclass. You can follow along in either IRB or by running a script from the command line.


 
 
class User
    # stuff will go here
end


By the end of this lesson, you'll be able to define a class so can track itsUserown user information.



Say wanted to assign a user ' s username. You might try something like this.


julia = User.new
julia.username = "coolgirl2000"
# NoMethodError: undefined method `username‘ for #<User:0x007fc6fa034148>


Let's pause to take a look at the error bit by bit.


    • NoMethodError: If I had to guess, I ' d say this likely have something to does with a method not existing.
    • undefined method ‘username‘: Suspicions confirmed. It looks like our code can ' t find a ' username ' method. That's makes sense, we never defined one.


But you weren ' t trying to create a new method! You were thinking on this likeusernamea variable, right?



Ruby has no how to distinguishing between variables and methods in this case, since they both come after.the, so it only supports instance methods.



?? What does we do now?! To treatusernameas a variable, you ' re going to need to fake this a bit. Let's write just enough code to stop this pesky error.


 
class User
  def username=(value)
  end
end


If you recall, the most characters is fair game with methods, including=. In this case, the argument stands in place of the value of yourvaluewant to assignusername.


julia.username=("coolgirl2000")
# => "coolgirl2000"


That does the trick ... sort of. There ' s an awful lot of syntax here, and it's a bit of a stretch to say this looks anything like thejulia.username = “coolgirl2000”we were going For.



Luckily, we can leave off the parentheses since those is optional for methods. These little shortcuts is known as syntactic sugar, since they make writing code with it just a bit sweeter??. Let's see how that looks.


 
julia.username= "coolgirl2001"
# => "coolgirl2001"


Wow, I already feel so much less stressed looking at that. The fact that's=pressed up against ISusernamestill bothering me. I can ' t stop looking at it.



It's going to bother me forever if you don ' t do something about it. Please, does something about it.



Syntactic sugar to the rescue again. When the A method ends=with, the Ruby rightfully assumes that your ' re creating a method for variable assignment. To make your life sweeter, Ruby lets your put a space before=the so it reads more like typical variable assignment, l IKE so:


 
julia.username = "coolgirl2002"
# => "coolgirl2002"


?? Boom. Check that out. I can sleep easily again. You ' ve just successfully created (the start of) Asetter method (sometimes called a mutator method).



A setter method is one which sets, or changes, the value of a variable belonging to a particular object.



Alright, let's check in on yourusername. If My math is correct, it should are set to right now“coolgirl2002”.


 
julia.username
# NoMethodError: undefined method `username‘ for #<User:0x007fc6fa034148>


This error again. You've seen this one before, but didn ' t do you already create this instance method?



Let's go ahead and write the bare minimum amount of code to make this error go away.


 
class User
  def username=(value)
  end

  def username
  end
end


This is the opposite of a setter method, a getter method. It exists to get the value of a variable belonging to an object. Let's see if the This works.


 
julia.username
# => nil


There's no error??, but it ' s also returningnilinstead of“coolgirl2002”. Already caught on ...



Neither yourusernamenor yourusername=methods actually do anything.



To make your getters and setter methods start working, you ' re going to need to capture theusernamevalues somewhere.



The problem here have to does with scope. How can the values of you capture in theusername=setter method is accessed in theusernamegetter method?



Much like instance methods, you can also use instance variables. Instance variables is variables that is scoped to the entire class.



This means a instance variable is defined, it can be used anywhere in that object.



An instance variable looks just like a regular variable, with one minor difference:it starts with@.


 
class User
  def username=(value)
    @username = value
  end

  def username
    @username
  end
end


Let's see if the this works before moving on.


 
julia.username = "coolgirl3000"
# => "coolgirl3000"
julia.username
# => "coolgirl3000"


?? nice!



The instance variable is now available to use by any of the@usernamemethods inside of aUserobject.



You can go ahead and make otherUserobjects now, and each one is able to track their own information.


walter = User.new
# => #<User:0x007fc6fa034328>
walter.username = "cooldude17"
# => "cooldude17"
walter.username
# => "cooldude17"


And one last check with the Julia to make sure she information is still accurate.


Julia.username # = "coolgirl3000"


Remember when we said this$global_variablesweren ' t the best solution? This is the best solution.



Very rarely'll you need a variable that's available to everything inside your application. Often, just want it available to one or a few objects.



Let me say that again:you would almost never need to use global variables ever again. If you find yourself using one,



There ' s a very good chance it can be do some other-the-using classes.



Getter and Setter methods is used so often in Ruby that there is even more shortcuts you can use for make your life sweet Er.



Why type more code than do really need to? Remember, Ruby is optimized for developer happiness.


 
class User
  attr_reader :username
  attr_writer :username
end


attr_readerattr_writerand ("attr" being shorthand for "attribute") is both methods that take care of creating getter and setter methods, R Espectively, for you.



Best of all, you can does this for as many attributes as you ' d. Perhaps you want the users to is able to the change their usernames, and not their birthdays.


 
class User
  attr_reader :username, :birthday
  attr_writer :username
end


There's no need to actually write off all those getter and setter methods yourself anymore!



One thing that confused me at first is the syntax ofattr_readerandattr_writer.



It didn ' t really look like anything I ' d ever seen before, at least don't until someone rewrote it for me this is:


Attr_reader (: Username,: birthday)


These is actually instance methods that is already baked in for the use.



All your is doing be passing in a Symbol representing the instance variable your ' d like to create getter and setter methods For.


Accessors


There ' s one last refactor we can does here. It's pretty common to need both a getters and a setter method for an attribute, so why isn't define both at once?



That's exactly whatattr_accessordoes.


 
class User
  attr_accessor :username
end


I know what do you ' re thinking. Yes, I did just string "along this emotional journey" only to end up writing three lines of code.



But think about it:now your know what these three lines of code actually do!



Along the learned about instance variables, some neat syntactic sugar, and getters and setters. Not bad.



Let's continue with theUserexample. This is what we have got at the moment:


 
class User
  attr_accessor :username
end


This was useful, but presents a slight issue. We don ' t want a user to ever is without a username.



The things is currently set up and you can easily does something like this:


colt = User.new
# => #<User:0x007fc6fb03ae98>
colt.username
# => nil


Because aUseris created without a defaultusernamevalue, Colt was left without a username until he goes in and sets one hi Mself.



?? This won't do.



There ' s a special instance method you can use the make sure an object is properly set up when it's created,initialize.



When you create a new object, the first thing Ruby would do are look for, andinitializerun it.



This makes are super handy for initial setup (for things like ... initializing an object with a username, maybe?).


 
class User
  attr_accessor :username

  def initialize
    @username = "its_colt_outside"
  end
end


Let's give this another go.


colt = User.new
# => #<User:0x007fc6fb03ae98 @username="its_colt_outside">
colt.username
# => "its_colt_outside"


?? Beautiful.



There ' s just one issue with the previous Example-we ' re hard-coding to being the“its_colt_outside”default username for every single user .



That's not going-to-help if the Orit wants to make a account for herself.



How about passing in the username as a argument right from the start, like a method, when creating the newUserobject?


Orit = User.new ("supermom")


To does this, you'll need to modify your class so thatUserit can accept arguments. It May is tempting to does something like this:


class User (username)  #  ... End


But as you'll quickly encounter, this would throw an error. This is a completely reasonable assumption, though.



Instead, you can include the argument as a part of theinitializemethod.



A Good A-remember-to-keep-in-mind-takes care ofinitializeeverything related to the initial set-up of an obj Ect.



SinceusernameThe argument deals with the initial set-up of a username, it belongs to theinitializemethod.


 
class User
  attr_accessor :username

  def initialize(username)
    @username = username
  end
end


Now the can initialize aUserobject with a username right when you create it.


orit = User.new("supermom")
# => #<User:0x007fc6fb03ae98 @username="supermom">
orit.username
# => "supermom"


This also safeguards is from creating a new user without a username.


mike = User.new
# ArgumentError: wrong number of arguments (0 for 1)


If you break apart that error, it shouldn ' t being too tough to figure out what's the issue is.


    • ArgumentError: This probably have something to does with the arguments passed into thisUserobject.
    • wrong number of arguments (0 for 1): Zero arguments were passed in, if theUserclass is expecting one.


Errors can seem scary, but often they contain vital information to help fix bugs in your code. Good error messages would tell you that exactly where you are need to make a fix.









Instance Variables in Ruby


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.