ตัวแปร @ ใน Ruby on Rails


294

ความแตกต่างระหว่าง@titleและtitleคืออะไร เนื่องจากทั้งคู่สามารถเป็นชื่อตัวแปรได้ นอกจากนี้ฉันจะตัดสินใจได้อย่างไรว่าควรใช้ตัวแปรชนิดใด มี@หรือไม่


ฉันจะบอกว่าบทช่วยสอนนี้ค่อนข้างเรียบร้อยเพื่ออธิบายสิ่งเหล่านี้ทั้งหมด: techotopia.com/index.php/ …
Hearen

คำตอบ:


426

titleเป็นตัวแปรท้องถิ่น มีอยู่ในขอบเขตเท่านั้น (บล็อกปัจจุบัน)

@title เป็นตัวแปรอินสแตนซ์ - และใช้ได้กับวิธีการทั้งหมดภายในชั้นเรียน

คุณสามารถอ่านเพิ่มเติมได้ที่นี่: http://strugglingwithruby.blogspot.dk/2010/03/variables.html

ใน Ruby on Rails การประกาศตัวแปรของคุณในคอนโทรลเลอร์เป็นตัวแปรอินสแตนซ์ ( @title) ทำให้สามารถดูได้


4
ขอบคุณสำหรับคำตอบมีคำถามติดตาม ... ภายในชั้นเรียนที่ฉันกำลังดำเนินการตัวแปรสมาชิกจะถูกสร้างขึ้นในขั้นต้นเช่น @options = {... } หลังจากนี้แม้ว่าวิธีการภายในการเข้าถึงชั้นเรียนและการเรียกใช้ฟังก์ชั่นกับตัวแปรที่ราวกับว่ามันเป็นท้องถิ่น (เช่น "options.merge ()") นี่เป็นรูปแบบที่ไม่ดีใช่ไหม มีเวทมนต์เกี่ยวกับวากยสัมพันธ์อื่น ๆ เกิดขึ้นไหม? (เช่นต้องการทำซ้ำแบบเงียบของตัวแปรหรือทำให้เป็น 'const' เพื่อให้ไม่สามารถแก้ไขได้ ฯลฯ )? ฉันมาจากมุมมอง C / C ++ และ Java และไวยากรณ์ที่ไม่ชัดเจนและเป็นตัวเลือกคือการทำให้ฉันบ้า!
Dan Devine

คลาสของคุณมี attr_accessor ที่กำหนดด้วยชื่อเดียวกัน @DanDevine หรือไม่ attr_accessor เป็นน้ำตาลซินแทกติกที่สร้าง getter \ setter ให้คุณ หากคุณได้รับค่าโดยไม่มีสัญลักษณ์ @ โค้ดจะได้รับตัวแปรเนื่องจากมันกำลังเรียกใช้ getter โปรดทราบว่าวิธีนี้ใช้ไม่ได้อีกวิธีหนึ่งคุณต้องใช้สัญลักษณ์ @ อย่างชัดเจนหากคุณตั้งค่า var มิฉะนั้นคุณจะตั้งค่า var ท้องถิ่น สไตล์นี้ดีหรือไม่? ยากที่จะพูด. ฉันชอบที่จะใช้ getter ไวยากรณ์ในวิธีการของฉันในกรณีที่ทะเยอทะยานอยู่เหนือ - ฉันชอบที่จะเคารพ encapsulation นั้นแม้ในชั้นเรียนของตัวเอง YMMV
Msencenb

30

ใช้@titleในตัวควบคุมของคุณเมื่อคุณต้องการให้ตัวแปรของคุณพร้อมใช้งานในมุมมองของคุณ

คำอธิบายนั่น@titleคือตัวแปรอินสแตนซ์และtitleเป็นตัวแปรโลคัลและ Rails ทำให้ตัวแปรอินสแตนซ์จากคอนโทรลเลอร์สามารถดูได้ สิ่งนี้เกิดขึ้นเนื่องจากโค้ดเทมเพลต (erb, haml และอื่น ๆ ) ถูกเรียกใช้งานภายในขอบเขตของอินสแตนซ์ของตัวควบคุมปัจจุบัน


ขอบคุณสำหรับสิ่งนี้! นี่เป็นคำตอบเดียวที่อธิบายว่าทำไม @variables ที่กำหนดไว้ในคลาสคอนโทรลเลอร์สามารถรับรหัสได้ในมุมมอง
AlexC

25

ความแตกต่างอยู่ในขอบเขตของตัวแปร @version มีให้สำหรับทุกวิธีของอินสแตนซ์ของคลาส

คำตอบสั้น ๆ , @variableถ้าคุณอยู่ในการควบคุมและคุณต้องการที่จะทำให้ตัวแปรที่มีให้ดูแล้วการใช้งาน

สำหรับคำตอบที่ยาวกว่านี้ลองทำดังนี้: http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_classes.html


14

@variables ถูกเรียกว่าตัวแปรอินสแตนซ์ในทับทิม ซึ่งหมายความว่าคุณสามารถเข้าถึงตัวแปรเหล่านี้ในวิธีใดก็ได้ภายในชั้นเรียน [ข้ามทุกวิธีในชั้นเรียน]

ตัวแปรที่ไม่มี@สัญลักษณ์เรียกว่าตัวแปรท้องถิ่นซึ่งหมายความว่าคุณสามารถเข้าถึงตัวแปรท้องถิ่นเหล่านี้ภายในวิธีการที่ได้ประกาศไว้เท่านั้น จำกัด อยู่ที่ขอบเขตในท้องถิ่น

ตัวอย่างของตัวแปรอินสแตนซ์:

class Customer
  def initialize(id, name, addr)
    @cust_id = id
    @cust_name = name
    @cust_addr = addr
  end

  def display_details
    puts "Customer id #{@cust_id}"
    puts "Customer name #{@cust_name}"
    puts "Customer address #{@cust_addr}"
  end
end

ในตัวอย่างข้างต้น@cust_id, @cust_name, @cust_addrมีการเข้าถึงในวิธีการอื่นในชั้นเรียน แต่สิ่งเดียวกันจะไม่สามารถเข้าถึงได้ด้วยตัวแปรท้องถิ่น


9

บทช่วยสอนเกี่ยวกับขอบเขตตัวแปรคืออะไร แสดงรายละเอียดบางอย่างได้ค่อนข้างดีเพียงล้อมรอบสิ่งที่เกี่ยวข้องไว้


+------------------+----------------------+
| Name Begins With |    Variable Scope    |
+------------------+----------------------+
| $                | A global variable    |
| @                | An instance variable |
| [a-z] or _       | A local variable     |
| [A-Z]            | A constant           |
| @@               | A class variable     |
+------------------+----------------------+

4

ตัวแปรท้องถิ่นสามารถเข้าถึงได้จากภายในบล็อกของการเริ่มต้น นอกจากนี้ตัวแปรโลคัลเริ่มต้นด้วยตัวอักษรตัวพิมพ์เล็ก (az) หรือขีดล่าง (_)

และตัวแปรอินสแตนซ์เป็นตัวอย่างของselfและเริ่มต้นด้วย@ตัวแปรอินสแตนซ์ยังเป็นของวัตถุเอง ตัวแปรอินสแตนซ์เป็นสิ่งที่คุณทำวิธีการเช่น.sendฯลฯ

ตัวอย่าง:

@user = User.all

@userเป็นตัวแปรเช่น

และตัวแปรอินสแตนซ์ Uninitialized มีค่าเป็น Nil


ดังนั้นสิ่งนี้จะอธิบายความแตกต่างระหว่าง@title& ได้titleอย่างไร
Richard Peck

ด้วยตัวแปรอินสแตนซ์เช่น @title คุณสามารถดำเนินการวิธีการต่าง ๆ ในขณะที่ตัวแปรท้องถิ่นที่คุณทำไม่ได้
Joe Hilton

1
แล้วมันจะแก้ไขคำถามได้อย่างไร? ดูเหมือนว่าคุณเพิ่งจะพูดถึงการกวดวิชา OP ต้องการทราบว่าเขาควรใช้@titleหรือไม่title
Richard Peck

ดังนั้นพวกเขาจึงควรใช้ตัวแปรเช่นถ้าพวกเขาต้องการที่จะดำเนินการวิธีการใด ๆ เช่น def ใหม่หรือ def สร้าง ฯลฯ
โจฮิลตัน

3
ไม่มีอะไรทำให้คุณหยุดทำ user = User.all และทำวิธีการกับผู้ใช้ แต่นี่ไม่ใช่ประเด็น
Jaro

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