Menu
CoddyTech

메서드에서의 self

Coddy Ruby 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 57개 중 9번째.

메서드 안에서 name = value는 클래스에 setter name=가 있더라도 항상 지역 변수를 만듭니다. setter를 호출하려면 수신자를 작성하세요: self.name = value:

class Player
  attr_accessor :level

  def initialize
    @level = 1
  end

  def broken_level_up
    level = level + 1
  rescue NoMethodError
    puts "level is a new local variable here, still nil"
  end

  def level_up
    self.level = level + 1
  end
end

p1 = Player.new
p1.broken_level_up
p1.level_up
puts p1.level

출력:

level is a new local variable here, still nil
2

리더 메서드에는 self.가 필요 없습니다. level과 self.level은 같은 메서드를 호출합니다. 일반적인 스타일에서는 Ruby에서 필요한 경우에만, 세터 앞에 self.를 씁니다.

class Rect
  attr_accessor :w, :h

  def initialize(w, h)
    @w = w
    @h = h
  end

  def area
    w * h
  end

  def double!
    self.w = w * 2
    self.h = self.h * 2
    self
  end
end

puts Rect.new(2, 3).double!.area

출력:

24

self.를 사용하여 initialize에서 setter를 호출하면 새 객체도 이후 변경과 동일한 검사를 통과하므로 규칙을 한곳에 둘 수 있습니다:

class Product
  attr_reader :price

  def initialize(price)
    self.price = price
  end

  def price=(value)
    raise ArgumentError, "price must be positive" if value <= 0

    @price = value
  end
end

puts Product.new(5).price
begin
  Product.new(0)
rescue ArgumentError => e
  puts e.message
end

출력:

5
price must be positive

self가 무엇인지는 코드가 실행되는 위치에 따라 달라집니다. 인스턴스 메서드 안에서는 인스턴스이고, 모든 메서드 바깥의 클래스 본문에서는 클래스 자체입니다:

class Robot
  puts "in the class body, self is #{self}"

  def whoami
    "in a method, self is a #{self.class}"
  end
end

puts Robot.new.whoami

출력:

in the class body, self is Robot
in a method, self is a Robot
challenge icon

챌린지

쉬움

클래스 Account에는 0보다 작은 값에 대해 balance cannot be negative와 함께 ArgumentError를 발생시키는 사용자 정의 setter balance=가 있습니다. 시작 잔액을 포함해 잔액이 변경될 때마다 self.를 사용하여 해당 setter를 거치도록 initialize(owner, balance), deposit(amount), withdraw(amount)를 완성하세요.

제공된 코드는 소유자와 시작 잔액을 읽은 다음 +n(입금) 또는 -n(출금) 명령을 읽습니다. 각 명령 뒤에 Ada: 120를 출력하거나, 오류 메시지와 변경되지 않은 잔액을 출력합니다. 시작 잔액이 유효하지 않으면 오류 메시지만 출력합니다.

코드는 account.rb에 작성하세요. main.rb에는 제공된 입력/출력 코드가 있으며 수정할 수 없습니다.

직접 해보기

require_relative 'account'

# 제공된 입출력 코드: 그대로 두세요
input = []
while (line = gets)
  input << line.chomp
end
begin
  account = Account.new(input[0], input[1].to_i)
  input.drop(2).each do |cmd|
    begin
      amount = cmd[1..].to_i
      cmd.start_with?("+") ? account.deposit(amount) : account.withdraw(amount)
    rescue ArgumentError => e
      puts e.message
    end
    puts "#{account.owner}: #{account.balance}"
  end
rescue ArgumentError => e
  puts e.message
end
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 Ruby 컴파일러