Giter VIP home page Giter VIP logo

ruby-oo-class-variables-private-methods's Introduction

Private Methods

Objectives

  1. Define private methods.
  2. Understand the context in which you will use such a method.
  3. See how private methods are defined.

Background: Instance and Class Methods

As we dive deeper into object orientation in Ruby, we've been working with different types of methods: instance and class methods. Remember that instance methods are called on instances of a class. Let's make the following class called Bartender.

class Bartender
  attr_accessor :name

  def initialize(name)
    @name = name
  end

  def intro
    "Hello, my name is #{name}!"
  end
end

phil = Bartender.new("Phil")
phil.intro
#=> "Hello, my name is Phil!"

intro is an instance method because we can call it on an instance of the Bartender class.

And class methods we call on the entire class itself, not the instance. Like if we had a method that kept track of all of the new instances of Bartender:

class Bartender
  attr_accessor :name

  BARTENDERS = []

  def initialize(name)
    @name = name
    BARTENDERS << self
  end

  def self.all
    BARTENDERS
  end

  def intro
    "Hello, my name is #{name}!"
  end
end

Here we're shoveling in every new instance of Bartender initialized into a constant that holds onto all bartenders. Then we have a class method self.all, which we'll call on the class itself to return all of the bartenders.

phil = Bartender.new("Phil")
nancy = Bartender.new("Nancy")

Bartender.all
#=> [#<Bartender:0x007f94cb16bbd0 @name="Phil">, #<Bartender:0x007f94cb16bb58 @name="Nancy">]

Public vs. Private Methods

Public Methods

We've already been writing public methods: intro and self.all. We can call them from outside the scope of the class declaration, like on the instance of the class or the class itself. Public methods are called by an explicit receiver: the instance of phil explicitly receives the method intro.

Private Methods

Private methods cannot be called by an explicit receiver. What does that mean? It means we can only call private methods within the context of the defining class: the receiver of a private method is always self.

Why Use Private Methods?

Private methods are a way of encapsulating functionality within a class. For example, a bartender can make a drink at a customer's request. Part of the process of making a drink includes choosing liquors, mixers, garnish, and stirring everything together. As a customer, you're permitted to ask the bartender for a drink (from a menu of options), but you can't instruct him or her on each step. The smaller steps that make up the bartender's job can be considered private methods.

Private methods also signal to other developers that this method is depended on by other methods in your program. It signals that they should beware of removing such a method for fear of breaking other parts of the program that they may not realize rely on it.

Building Private Methods

We've already written a private method in our Bartender class: initialize.

phil.initialize
#=>NoMethodError: private method `initialize' called for #<Bartender:0x007fafb4257dd8 @name="Phil">

Private methods, aside from initialize, are usually written with the word private above them. Let's make a private method called choose_liquor

We'll also create a public method make_drink that calls on choose_liquor.

class Bartender
  attr_accessor :name

  BARTENDERS = []

  def initialize(name)
    @name = name
    BARTENDERS << self
  end

  def self.all
    BARTENDERS
  end

  def intro
    "Hello, my name is #{name}!"
  end

  def make_drink
    @cocktail_ingredients = []
    choose_liquor
    choose_mixer
    choose_garnish
    return "Here is your drink. It contains #{@cocktail_ingredients}"
  end

  private

  def choose_liquor
    @cocktail_ingredients.push("whiskey")
  end

  def choose_mixer
    @cocktail_ingredients.push("vermouth")
  end

  def choose_garnish
    @cocktail_ingredients.push("olives")
  end

end

If we try to call #choose_liquor with an instance of a bartender, we get an error:

phil.choose_liquor
# NoMethodError: private method `choose_liquor' called for #<Bartender:0x007f9f5b03d318 @name="Phil">

Again, private methods cannot be called by an explicit receiver. Because phil is the explicit receiver of choose_liquor, the method errors out.

However, if we call make_drink, the choose_liquor method works. What gives?

phil.make_drink
# Here is your drink. It contains ["whiskey", "vermouth", "olives"]

The choose_liquor method was called without any receiver. Ruby sees the missing receiver and assumes it to be self, or the current object. When choose_liquor is called, self is an instance of Bartender. Only a Bartender object can tell itself to choose a liquor, a mixer, and a garnish. Phil can tell himself to choose a liquor, garnish, etc., but we cannot instruct Phil to do so. Private methods restrict an outsider from calling methods that belong to an object. However, we, as customers, are free to ask a bartender to make us a drink (make_drink).

Note: Prior to version 2.7 of Ruby, if we tried to call our private methods from #make_drink using self (e.g., self.choose_liquor rather than just choose_liquor), we would get that same 'private method' error. However, beginning with version 2.7 of Ruby, private methods can be called from other methods in the Class with or without the self keyword.

ruby-oo-class-variables-private-methods's People

Contributors

ahimmelstoss avatar babyshoes avatar deniznida avatar fislabstest avatar fs-lms-test-bot avatar ga-be avatar ihollander avatar jeffkatzy avatar jonbf avatar kevinmirc avatar lizbur10 avatar maxwellbenton avatar msuzoagu avatar onyoo avatar pletcher avatar rolandobrown avatar samnags avatar sarogers avatar sophiedebenedetto avatar

Watchers

 avatar  avatar  avatar

ruby-oo-class-variables-private-methods's Issues

Weird Formatting in Canvas

PMissue

Not sure if this is just an issue with me or as a whole, but the attached screenshot is how this shows up in my canvas. I looked at the readme on github as a workaround but wanted to make someone else aware of the issue.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.