Ruby: The Bad Parts [ปิด]


20

เมื่อเร็ว ๆ นี้ฉันอ่านหนังสือ "Javascript: The Good Parts" ของ Crockford และหนึ่งในสถานที่สำคัญคือภาษาการเขียนโปรแกรมสามารถมีฟีเจอร์ที่ไม่ดีซึ่งโปรแกรมเมอร์ควรหลีกเลี่ยง

ฉันเป็น Rubyist และในขณะที่ฉันรักภาษามีค่าเสมอในการรับมุมมอง ดังนั้นสิ่งที่คุณเห็นว่าเป็นคุณลักษณะที่เลวร้ายที่สุด (เช่นวิธีการเรียนการปฏิบัติ) ในทับทิม? ความตั้งใจของฉันที่นี่ไม่ได้เริ่มต้นการโต้เถียงเกี่ยวกับข้อดีของภาษาหรือความเร็วของมันและอื่น ๆ แต่ฉันต้องการอภิปรายว่าคุณลักษณะใดที่คุณคิดว่าเป็นอันตราย / ลำบาก / เจ็บปวดที่จะใช้โดยอิงจากประสบการณ์ที่ผ่านมา


1
ฉันไม่เคยเป็นแฟนตัวยงของการใช้คำว่า "จบ" จากนั้นส่วนผสมของคำว่า "{" และ "}" ก็ยิ่งน่ารำคาญยิ่งขึ้นไปอีก มันทำให้ฉันรู้สึกซาบซึ้งในรูปแบบของ Python หรือทำให้ตรงขึ้น {&} แม้ว่าใคร ๆ ก็สามารถเถียงกันเรื่องนี้ไปมาได้และในที่สุดมันก็มีหลายอย่างที่เกี่ยวข้องกับความชอบส่วนตัว ฉันได้ยินบางคนบอกว่าทับทิมใช้ส่วนที่น่าเกลียดที่สุดของ Python และ Perl และรวมเข้าด้วยกัน ฉันสนุกกับการเรียนรูบี้

ฉันค่อนข้างชอบคำถามนี้จริง ๆ และจะรอคอยคำตอบ แต่ก็ยังโหวตให้ปิด ฉันไม่คิดว่ามันเหมาะสมกับ Stack Overflow (เนื่องจากอาจเป็นอัตนัย / โต้แย้งเกินปลายเปิด ฯลฯ )
stakx

ฉันคิดว่ามันคุ้มค่าที่จะพูดคุยกันเพราะมันจะช่วยส่องสว่างการปฏิบัติที่เป็นอันตรายที่ควรหลีกเลี่ยง ฉันเห็นประเด็นของคุณและแก้ไขคำถามให้แคบลง

9
ฉันไม่เห็นว่าคำถามนี้แตกต่างจากคำถามเช่นอะไรคือสิ่งที่คุณต้องการปรับปรุงในภาษา Ruby , อะไรคือทับทิม Gotchas เป็นมือใหม่ควรจะเตือนเกี่ยวกับอะไร? , อะไรคือปัญหาที่แท้จริงของโลกกับทับทิม? หรือคำถามอื่น ๆ ที่มีมูลค่ามหาศาลที่เกี่ยวกับจุดปวดของทับทิม ยิ่งกว่านั้นหากคำถามนี้ถูกพัฒนาขึ้นเพื่อแยกแยะความแตกต่างจากคำถามอื่น ๆ พวกเขาก็จะอยู่ในProgrammers.SEไม่ใช่ StackOverflow
Jörg W Mittag

2
ฉันต้องตรวจตาฉันคิดว่าชื่อของคำถามนี้คือ "Ruby: The Brad Pitts"
oosterwal

คำตอบ:


8

คุณควรดูPython vs Ruby: A Battle to The Deathโดย Gary Bernhardt เขาทำให้คำพูด:

สิ่งที่ฉันพบว่าน่าเกลียดใน Ruby คือสิ่งที่ทำให้ซอฟต์แวร์ Ruby ที่น่าทึ่งอย่าง RSpec เป็นไปได้และ Python นั้นไม่มีทางได้เลย

ในขณะที่เขาพูดถึง Python โดยเฉพาะอย่างยิ่งเขาสัมผัสกับสิ่งต่าง ๆ มากมายที่เป็นเรื่องแปลกใน Ruby หนึ่งในวิชาที่ครอบคลุมใหญ่คือลิง patching

วัตถุทับทิม (แตกต่างจากวัตถุในภาษาเชิงวัตถุอื่น ๆ ) สามารถปรับเปลี่ยนทีละรายการ คุณสามารถเพิ่มวิธีการได้บนพื้นฐานต่อวัตถุเสมอ ใน Ruby พฤติกรรมหรือความสามารถของวัตถุสามารถเบี่ยงเบนจากสิ่งที่จัดทำโดยระดับของมัน

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


Javascript อนุญาตให้คุณจัดการกับวัตถุด้วยวิธีนี้เช่นกัน
0112

8

บางคนคิดว่าทับทิมในแง่ของทับทิมบนรางรถไฟและมันค่อนข้างน่ารำคาญเพราะภาษานั้นตั้งอยู่บนตัวของมันเอง


7

ฉันคิดว่าคุณสมบัติที่แย่ที่สุดคือopen classesให้คุณเปลี่ยนพฤติกรรมของอินสแตนซ์ปัจจุบันและอนาคตทั้งหมดของคลาสที่เปลี่ยนแปลง

ส่วนที่เป็นปัญหาของคุณสมบัตินี้คือการเปลี่ยนแปลงเหล่านี้เกิดขึ้นระหว่างรันไทม์เมื่อตัวแปล Ruby มาตามคำนิยามซึ่งอาจนานหลังจากที่คุณสร้างอินสแตนซ์ของวัตถุสองอันซึ่งเปลี่ยนพฤติกรรมของพวกเขาในทันที

ในฐานรหัสขนาดใหญ่สิ่งนี้อาจส่งผลให้ยากมากที่จะหาข้อบกพร่อง - โดยเฉพาะอย่างยิ่งเมื่อประกอบกับความอ่อนแอของ Ruby (เมื่อเทียบกับ CLR หรือ JVM) การแก้จุดบกพร่องและการใช้คุณสมบัติอื่น ๆ (เช่นeval) ในบริบทนี้ มันค่อนข้างยากที่จะค้นหาตำแหน่งที่เกิดการเปลี่ยนแปลงระดับโลกนี้ นั่นคือถ้าคุณมาถึงจุดที่คุณสงสัยว่าคลาส 'ถูกต้อง' ก่อให้เกิดปัญหา! จากประสบการณ์ของฉันคุณมักจะเริ่มต้นด้วยการไล่ล่าห่านป่าเนื่องจากปัญหาเริ่มปรากฏที่วัตถุโดยใช้ผู้ร้ายตัวจริง

ดังนั้นสิ่งที่ดีที่สุดคือการหยุดใช้คลาสที่เปิดอยู่ ( #extendและการเปลี่ยนแปลงใน a Moduleคือ IMHO ปลอดภัยกว่าง่ายกว่าที่จะเข้าใจและทดสอบได้ดีกว่า) หรือถ้าไม่สามารถหลีกเลี่ยง:

  • ขยายคลาสที่มีลักษณะการทำงานใหม่เท่านั้น (เช่นไม่แทนที่พฤติกรรมที่มีอยู่)
  • มีสถานที่ที่กำหนดไว้ในทรีซอร์สโค้ดซึ่งจะต้องวางส่วนขยายทั้งหมดที่ใช้คลาสที่เปิดอยู่
  • อย่าใช้#evalและเพื่อน ๆ ในการสร้างชั้นเรียนเปิด
  • ใส่การเรียนแบบเปิดทั้งหมดไว้ในแผนภูมิขนาดใหญ่ที่ผู้พัฒนาทุกคนสามารถเห็นได้ - และทำให้ชัดเจนว่าการเปลี่ยนแปลงใด ๆ ในพวกเขาคือ 'การตัดสินใจเชิงสถาปัตยกรรม' ที่ส่งผลต่อฐานรหัสทั้งหมด (ซึ่งพวกเขาทำ) และไม่ใช่สถานที่ สำหรับงานปัจจุบันของคุณ

5

เหตุผลที่ใหญ่ที่สุดที่ฉันไม่ได้ใช้ทับทิม: มันช้ากว่ากากน้ำตาลในเดือนมกราคมที่ขั้วโลกเหนือในช่วงยุคน้ำแข็ง ภาษาที่ใช้ในการเปรียบเทียบเป็นวิทยาศาสตร์ที่ไม่แน่นอน แต่ Ruby ปรากฏช้ากว่าจาวาสคริปต์และ Python อย่างมาก


นั่นคือประสบการณ์ของฉันด้วย
Chuck Stephanski

2
แอปพลิเคชันที่คุณพัฒนาซึ่งทับทิมช้าเกินไปคืออะไร ฉันหมายความว่าฉันเชื่อว่าคุณเมื่อคุณพูดว่าช้า แต่ทำไมคุณถึงไม่บรรลุเป้าหมายของคุณ
David

1
ฉันคิดว่า Ruby นั้นยอดเยี่ยมเมื่อคุณต้องการสร้างต้นแบบและต้องการให้มันทำอย่างรวดเร็วสิ่งที่ไม่ใหญ่โตและจะไม่กระทืบจำนวนมาก หากคุณคาดว่าจะเคี้ยว CPU รอบมากตลอดเวลาโปรแกรมเมอร์ที่ดีคนใดรู้วิธีใช้ C หรือ C ++
Jeff Welling

1
@ David: ฉันจะพิจารณาใช้ Ruby สำหรับรหัสประมวลผลลำดับดีเอ็นเออย่างง่าย แต่ฉันทำไม่ได้เพราะ Python เติมช่องว่างที่คล้ายกันมีคุณสมบัติที่คล้ายกันและเร็วกว่ามาก ถ้าฉันเต็มใจที่จะลดระดับลง D จะเร็วขึ้นและยังสะดวกกว่า
dsimcha

1
@Jeff: เห็นด้วย แต่ C และ C ++ เป็นความเจ็บปวดที่จะเขียนจุดของภาษาระดับสูงเช่น Ruby คือการหลีกเลี่ยงการจัดการกับความเจ็บปวดนี้ให้มากที่สุด ยิ่งพวกเขาช้าก็ยิ่งบรรลุเป้าหมายนี้ได้น้อยลงเท่านั้น Ruby ช้าแม้กระทั่งภาษาไดนามิกระดับสูง นั่นและ NumPy / SciPy คือเหตุผลที่ฉันใช้ Python แทนเมื่อฉันต้องการภาษาไดนามิกระดับสูง
dsimcha

4

หากสามารถขยายเป็น Ruby on Rails ได้:

  1. ความจริงที่ว่าตรรกะฐานข้อมูลให้auto_incrementคีย์หลักทุกตารางรวมถึงตารางที่ไม่ต้องการและไม่ควรมี

  2. ความจริงที่ว่าคีย์ผสมไม่ได้รับการสนับสนุนเลย

สำหรับ Ruby ธรรมดา ๆ ที่ฉันถนัดจะเหมือนกับภาษาใด ๆ ที่แลกเปลี่ยนความปลอดภัยเพื่อความหมาย; มันง่ายมากที่จะทำด้วยโค้ดเพียงเล็กน้อย แต่มันก็เป็นเรื่องง่ายที่จะทำเรื่องยุ่ง ๆ กับโค้ดจำนวนมาก


โปรดดูการแก้ไขของฉันเมื่อฉัน จำกัด ขอบเขตของคำถามให้แคบลง ฉันจะเริ่มอีกอันหนึ่งขนานสำหรับ Rails หากคำถามนี้มีการอนุมัติแล้ว

1
ขออภัย แต่คุณเข้าใจผิดว่าไม่ใช่ทุกตารางในแอพ Rails จำเป็นต้องมีauto_incrementid โดยเฉพาะอย่างยิ่งการเข้าร่วมตารางสำหรับ has_and_belongs_to_many ความสัมพันธ์จะแนะนำให้ไม่มีคอลัมน์ id อย่างชัดเจน
Brett Bender

@Brett - เป็นส่วนที่ค่อนข้างใหม่หรือไม่? เมื่อฉันเล่นกับมันเมื่อต้นปี 2551 มันไม่ได้มีคุณสมบัติเหล่านั้นอย่างแน่นอน ไม่ว่าในกรณีใดมันยอดเยี่ยมมากที่มีให้บริการในตอนนี้

1
@aroth: ฉันไม่แน่ใจว่าคนอื่นจะพิจารณา "ค่อนข้างใหม่" หมายถึง "ในช่วงสามปีที่ผ่านมา" :-)

มีทางเลือกอื่นสำหรับ RailS 'ActiveRecord ที่เรียกว่าDataMapperซึ่งไม่ได้ให้ความเห็นว่าเป็น ActiveRecord
Endy Tjahjono

3

Ruby รวบรวม metaprogramming (การสะท้อนการใคร่ครวญ) การเขียนโปรแกรมแบบหลายกระบวนทัศน์และพลวัตในระดับที่ไม่ธรรมดา มันง่ายที่จะยิงตัวคุณเองด้วยพลังและความยืดหยุ่น

ลำบาก? Ruby มีความสามารถในการอ่านหรือทำลายไม่ได้อย่างมาก ฉันเห็นโค้ดที่ดูเหมือนว่าอยู่ในสคริปต์ Bash

การปฏิบัติที่ไม่ดี? Rubyist บางคนมีความฉลาดกว่าสติปัญญา พวกเขาเขียนและแบ่งปันเทคนิคที่แสดงออกถึงความฉลาดของพวกเขา แต่สิ่งนี้จะสร้างโค้ดที่อ่านไม่ได้และเปราะบาง

นอกเหนือจากนี้: Javascript เป็นหายนะจากการออกแบบและหนังสือ "The Good Parts" พยายามที่จะแยกความสวยงามที่ซ่อนอยู่ออก Perl ภาษาที่นิยมใช้ "มีมากกว่าหนึ่งวิธีที่จะทำ" (นั่นคือความยืดหยุ่น) มีหนังสือที่คล้ายกันใน "Perl, Best Practices" ประวัติศาสตร์ของ Perl เป็นหนึ่งในการทดลองและประสบการณ์ที่ยากชนะ "วิธีปฏิบัติที่ดีที่สุด" แสดงถึงความรู้ Perl 6 จะเป็นฉันคิดว่ามันยุติธรรมที่จะพูดการรีบูตของภาษาตามความรู้นั้นและอีกมากมาย ทับทิมอาจประสบปัญหาที่คล้ายกัน

@ James และลูป ... เมื่อคุณทำลูปเป็น ruby ​​แล้วจะเรียก ".each" ดังนั้นคำว่า "สำหรับ" จึงเป็นน้ำตาลประโยคสำหรับผู้ที่รู้สึกสะดวกสบายกับลูปแบบ C แต่ในฐานะนักทับทิมคุณจะใช้ตัววนซ้ำเช่น. map, .inject, .each_with_object ตลอดเวลา คุณจะไม่ต้องเขียน a for loop ด้วยบางอย่างเช่น "i = 0; i> 6; i ++" ใน ruby ​​ดังนั้นคุณจึงเลิกนิสัย @ andrew ... ruby ​​วาทศิลป์ไม่ได้สนับสนุนลูป


-1

นี่เป็นเรื่องเกี่ยวกับโปรแกรมเมอร์มากกว่าภาษา แต่ทำไมโปรแกรมเมอร์ Ruby ถึงเกลียดชังลูปมากนัก?

ฉันรู้ว่า Ruby มี:

someCollection.each do |item|
   ...
end

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

ฉันถามมาหลายครั้งแล้วและไม่เคยได้รับคำตอบที่ดีเลย

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


1
เมื่อฉันยังมีคำตอบ "มันกดปุ่มน้อย" ซึ่งเป็นเท็จอย่างชัดเจน ... :-)
เจมส์

2
ทฤษฎีสองข้อ: 1) การใช้forลูปเป็นสิ่งที่ n00bs ทำ ผู้ที่กำลังเขียนโปรแกรม C ใน Ruby 2) บล็อกมีการใช้จำนวนมากใน Ruby ดังนั้นการใช้บางสิ่งที่ไม่เหมือนบล็อกเป็นเพียงความพยายามทางจิตที่พิเศษ
Andrew Grimm

3
ในขณะที่ฉันเพิ่งเริ่มเรียนรู้ Ruby บล็อกเป็นสิ่งที่ฉันชอบและพลาดเมื่อพยายามใช้ Python สำหรับวงจะทำในสิ่งเดียวกันหรือไม่ แน่นอนสำหรับฉันแล้วสไตล์แบบนี้เหมาะกับความชอบมากกว่าห่วง
Jetti

2
@ อันที่จริงแล้วคำตอบที่ 1 ของคุณคือขยะที่ฉันได้รับเมื่อฉันถูกถามมาก่อน ไม่มีเหตุผลที่แท้จริงด้วยการดูถูกที่ลึกซึ้งด้านบน @Wayne @Jetti และ @andrews คำตอบที่ 2: ขอบคุณ ยุติธรรมพอสมควรแล้ว
James

1
หากคุณหมายถึง "ปรับปรุง" สำหรับลูป (aka. สำหรับ <value> ใน <expression> do ... ) จะไม่มีความแตกต่างจาก #each ที่ใช้งานอยู่และมีลักษณะใกล้เคียงกับญาติที่ใช้กันทั่วไป #inject, #collect, # ปฏิเสธ ฯลฯ หากคุณกำลังพูดถึงลูปที่จัดทำดัชนีสไตล์ 'C' (aka. สำหรับ int i = 0; i <what; ++ i) ความแตกต่างคือว่าข้อผิดพลาด "off by one" เป็นไปไม่ได้และ b) มันทำให้เจตนาของลูปของคุณชัดเจน - #each หมายถึง "สำหรับแต่ละองค์ประกอบสร้างผลข้างเคียง" ห่วงสำหรับคุณต้องอ่านทั้งวงเพียงเพื่อให้ได้ส่วนสำคัญของจุดประสงค์ของมัน
Alexander Battisti

-1

โดยทั่วไปฉันจะหลีกเลี่ยงสิ่งที่เพิ่มเข้ามาเพื่อให้เข้ากันได้กับภาษาอื่น ๆ ยกตัวอย่างเช่น Perlisms for x in yและ


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