Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

เชี่ยวชาญ Keyword `self` ใน Ruby: คู่มือชัดเจนสำหรับทุก Developers

วันนี้พูดถึง self เขียน Ruby มาสักพักน่าจะ internalize แนวคิด self แล้ว อ่าน/เขียนโปรแกรม self อยู่หลังหัวเสมอ

แต่นักพัฒนาที่ใหม่ self น่ฮือสับ เปลี่ยนแปลงตลอดแต่ไม่ explicit ในโค้ด คาดว่าแค่รู้

ปัญหาเยอะของ beginners มาจากไม่เข้าใจ self เคย "หาย" instance variable หรือปวดหัวว่า data ไหน visible ให้ mixin เพราะไม่เข้าใจ self ใน context นั้น

โพสต์นี้ดู self ใน everyday situations หลากหลาย

self คืออะไร?

อาจได้ยินว่า everything in Ruby is an object ถ้าเป็นจริง ทุกโค้ดที่เขียน "เป็นของ" object ใด object หนึ่ง

self คือ special variable ชี้ไป object ที่ "เป็นเจ้าของ" currently executing code Ruby ใช้ self ทุกที่:

  • Instance variables: @myvar
  • Method และ constant lookup
  • ตอน define methods, classes, modules

ทฤษฎี self ชัดเจน แต่ปฏิบัติ tricky situations วิ่งออกมาได้ง่าย นั่นคือเหตุผลที่เขียนโพสต์นี้

ตัวอย่าง self

ผ่านหลายตัวอย่าง ถ้าแรก basic เกินไป อ่านต่อ ได้ advanced ขึ้นเรื่อยๆ

ภายใน Instance Method

โค้ดด้านล่าง reflect เป็น instance method เป็นของ object ที่สร้างผ่าน Ghost.new ดังนั้น self ชี้ object นั้น


class Ghost
  def reflect
    self
  end
end

g = Ghost.new
g.reflect == g # => true

ภายใน Class Method

ตัวอย่าง reflect เป็น class method ของ Ghost Class methods คลาสตัวเอง "เป็นเจ้าของ" method self ชี้ class


class Ghost
  def self.reflect
    self
  end
end

Ghost.reflect == Ghost # => true

เหมือนกันกับ "class" methods ใน modules:


module Ghost
  def self.reflect
    self
  end
end

Ghost.reflect == Ghost # => true

จำไว้: classes และ modules ถูก treat เป็น objects ใน Ruby พฤติกรรมนี้ไม่ต่างจาก instance method behavior ตัวแรกมาก

ภายใน Class หรือ Module Definition

Feature ทำ Ruby เหมาะ frameworks เช่น Rails: execute arbitrary code ภายใน class/module definitions ได้ เวลาวางโค้ดใน class/module definition มันรันเหมือน Ruby code ปกติ ความต่างคือค่า self

เห็นได้ self ชี้ class หรือ module ที่กำลัง defined:


class Ghost
  self == Ghost # => true
end

module Mummy
  self == Mummy # => true
end

ภายใน Mixin Methods

Mixed-in methods behave เหมือน "normal" instance/class methods เกี่ยวกับ self ทำ sense ไม่งั้น mixin interact กับ class ที่ mix เข้าไม่ได้

Instance methods

แม้ reflect defined ใน module self เป็น instance ของ class ที่ mix เข้า


module Reflection
  def reflect
    self
  end
end

class Ghost
  include Reflection
end

g = Ghost.new
g.reflect == g # => true

Class methods

เวลา extend class mix in class methods self behave เหมือน normal class methods


module Reflection
  def reflect
    self
  end
end

class Ghost
  extend Reflection
end

Ghost.reflect == Ghost # => true

ภายใน Metaclass

น่าจะเคยเหย shortcut ยอดนิยม define class methods หลายๆ ตัว:


class Ghost
  class << self
    def method1
    end
    def method2
    end
  end
end

class << foo syntax น่าสนใจ เข้าถึง metaclass ของ object - เรียกว่า "singleton class" หรือ "eigenclass" วางแผน cover metaclasses ลึกในโพสต์หน้า ตอนนี้แค่รู้ว่า metaclass ที่ Ruby เก็บ methods unique to specific object

เข้าถึง self จากใน class << foo block ได้ metaclass:


class << "test"
  puts self.inspect
end
# => #>

นอก Class ใดๆ

รันโค้ดนอก class ใดๆ Ruby ยังให้ self ชี้ "main" ซึ่งเป็น instance ของ Object:


puts self.inspect # => main