สร้างตัวแปรโมดูลใน Ruby


112

มีวิธีใดในการสร้างตัวแปรในโมดูลใน Ruby ที่จะทำงานคล้ายกับตัวแปรคลาสหรือไม่? สิ่งที่ฉันหมายถึงคือมันจะสามารถเข้าถึงได้โดยไม่ต้องเริ่มต้นอินสแตนซ์ของโมดูล แต่สามารถเปลี่ยนแปลงได้ (ไม่เหมือนกับค่าคงที่ในโมดูล)

คำตอบ:


159

Ruby สนับสนุนตัวแปรคลาสในโมดูลโดยกำเนิดดังนั้นคุณสามารถใช้ตัวแปรคลาสได้โดยตรงและไม่ใช่ตัวแปรพร็อกซีหรือคลาสหลอก:

module Site
  @@name = "StackOverflow"

  def self.setName(value)
    @@name = value
  end

  def self.name
    @@name
  end
end

Site.name            # => "StackOverflow"
Site.setName("Test")
Site.name            # => "Test"

5
+1 อันที่จริงฉันคิดว่าคำว่า 'ตัวแปรคลาส' นั้นทำให้เข้าใจผิด คลาสเป็นกรณีพิเศษของโมดูลและตัวแปรคลาสสามารถกำหนดได้ในโมดูล ควรเรียกว่าตัวแปรโมดูล
sawa

3
@sawa: มันค่อนข้างทำให้เข้าใจผิด แต่เป็นสิ่งที่ Ruby ใช้เอง: defined?(@@foo) => "class variable".
Andrew Grimm

1
หรืออาจเรียกว่าฟิลด์คงที่ ดูเหมือนว่านั่นคือสิ่งที่พวกเขาเป็น
Peter Ajtai

@coreyward เฮ้ความผิดพลาดของฉัน ทำไมต้องมีตัวแปรคลาส '@@' สองตัว ไม่ถือว่าเป็นกลิ่นรหัสโดยเฉพาะอย่างยิ่งหากมีการขยายคลาสเพื่อใช้ตัวแปรคลาส? ฉันกำลังทดสอบสิ่งนี้และฉันรู้ว่าฉันได้ผลลัพธ์เดียวกันจาก@ตัวแปรอินสแตนซ์เดียว มีเหตุผลเฉพาะในการใช้ตัวแปรคลาสหรือไม่? ขอบคุณสำหรับการตอบกลับ.
fabbb

2
ทำไมการโทรที่แตกต่างกันในตอนท้าย: T.getและT::get?
intrixius

31

หากคุณไม่จำเป็นต้องเรียกใช้จากภายในอินสแตนซ์คุณสามารถใช้ตัวแปรอินสแตนซ์ภายในตัวโมดูล

module SomeModule
  module_function
  def param; @param end
  def param= v; @param = v end
end

SomeModule.param
# => nil
SomeModule.param = 1
SomeModule.param
# => 1

@paramจากนั้นตัวแปรอินสแตนซ์จะเป็นของโมดูลSomeModuleซึ่งเป็นอินสแตนซ์ของModuleคลาส


23

คุณสามารถตั้งค่าตัวแปรอินสแตนซ์คลาสในโมดูล

module MyModule
   class << self; attr_accessor :var; end
end

MyModule.var = 'this is saved at @var'

MyModule.var    
=> "this is saved at @var"

+1 แต่ฉันจะเน้นว่าตัวแปรอินสแตนซ์คลาสนั้นแตกต่างจากตัวแปรคลาส
Andrew Grimm

4
ใช่ทั้งหมด .. และ btw .. ฉันไม่แนะนำให้ใช้ตัวแปรคลาสเลย .. สิ่งที่ไม่คาดคิดเกิดขึ้นเมื่อคุณใช้ .. ตรวจสอบบทความนี้เพื่อดูตัวอย่างบางส่วนoreillynet.com/ruby/blog/2007/01/…
Orlando

8

คุณยังสามารถเริ่มต้นค่าภายในนิยามโมดูล:

module MyModule
  class << self
    attr_accessor :my_variable
  end
  self.my_variable = 2 + 2
end

p MyModule.my_variable
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.