Ruby มีอะไรที่ Python ไม่ได้และในทางกลับกัน


263

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

ดังนั้นจึงน่าสนใจที่จะแสดงรายการความแตกต่างอย่างเป็นกลาง ดังนั้นจึงไม่มี "ลูกแกะของงูหลามดูด" แทนที่จะอธิบายว่า lambdas ของ Ruby สามารถทำอะไรได้บ้างที่ Python ทำไม่ได้ ไม่มีตัวตน โค้ดตัวอย่างดี!

กรุณามีความแตกต่างหลายอย่างในหนึ่งคำตอบโปรด และโหวตคนที่คุณรู้ว่าถูกต้องและคนที่คุณรู้ว่าไม่ถูกต้อง นอกจากนี้ความแตกต่างในไวยากรณ์ไม่น่าสนใจ เรารู้ว่า Python ทำด้วยการเยื้องสิ่งที่ Ruby ทำกับวงเล็บใหญ่และส่วนท้ายและ @ นั้นเรียกว่า self in Python

UPDATE: ตอนนี้เป็นวิกิชุมชนแล้วเราจึงสามารถเพิ่มความแตกต่างใหญ่ ๆ ได้ที่นี่

Ruby มีการอ้างอิงคลาสในเนื้อหาคลาส

ใน Ruby คุณมีการอ้างอิงถึงคลาส (ตัวเอง) แล้วในเนื้อหาของคลาส ใน Python คุณไม่มีการอ้างอิงถึงคลาสจนกว่าจะเสร็จสิ้นการสร้างคลาส

ตัวอย่าง:

class Kaka
  puts self
end

ตนเองในกรณีนี้คือคลาสและรหัสนี้จะพิมพ์ "Kaka" ไม่มีวิธีพิมพ์ชื่อคลาสหรือวิธีอื่นเข้าถึงคลาสจากเนื้อหานิยามคลาสใน Python (นิยามเมธอดภายนอก)

คลาสทั้งหมดไม่แน่นอนใน Ruby

สิ่งนี้ช่วยให้คุณพัฒนาส่วนขยายไปยังคลาสหลัก นี่คือตัวอย่างของการขยายราง:

class String
  def starts_with?(other)
    head = self[0, other.length]
    head == other
  end
end

Python (จินตนาการว่าไม่มี''.startswithวิธี):

def starts_with(s, prefix):
    return s[:len(prefix)] == prefix

คุณสามารถใช้มันในลำดับใดก็ได้ (ไม่ใช่แค่สตริง) ในการใช้งานคุณควรนำเข้าอย่างชัดเจนเช่น,from some_module import starts_withเช่น

Ruby มีคุณสมบัติการเขียนสคริปต์เหมือน Perl

Ruby มี regexps ชั้นหนึ่ง, $ -variables, บรรทัด awk / perl โดย line input loop และคุณสมบัติอื่น ๆ ที่ทำให้เหมาะกับการเขียนเชลล์สคริปต์ขนาดเล็กที่ทำให้ไฟล์ข้อความหรือทำหน้าที่เป็นรหัสกาวสำหรับโปรแกรมอื่น ๆ

ทับทิมมีความต่อเนื่องชั้นหนึ่ง

ขอบคุณคำสั่ง callcc ใน Python คุณสามารถสร้างความต่อเนื่องโดยใช้เทคนิคต่าง ๆ แต่ไม่มีการสนับสนุนในภาษา

ทับทิมมีบล็อก

ด้วยคำสั่ง "do" คุณสามารถสร้างฟังก์ชั่นที่ไม่ระบุชื่อหลายบรรทัดใน Ruby ซึ่งจะถูกส่งผ่านเป็นอาร์กิวเมนต์ในวิธีที่อยู่ข้างหน้า do และเรียกจากที่นั่น ใน Python คุณสามารถทำได้โดยการส่งเมธอดหรือกับตัวกำเนิด

ทับทิม:

amethod { |here|
    many=lines+of+code
    goes(here)
}

Python (บล็อก Ruby สอดคล้องกับโครงสร้างที่แตกต่างใน Python):

with amethod() as here: # `amethod() is a context manager
    many=lines+of+code
    goes(here)

หรือ

for here in amethod(): # `amethod()` is an iterable
    many=lines+of+code
    goes(here)

หรือ

def function(here):
    many=lines+of+code
    goes(here)

amethod(function)     # `function` is a callback

ที่น่าสนใจคือข้อความประกาศความสะดวกสบายใน Ruby สำหรับการเรียกบล็อกนั้นเรียกว่า "yield" ซึ่งใน Python จะสร้างเครื่องกำเนิด

ทับทิม:

def themethod
    yield 5
end

themethod do |foo|
    puts foo
end

งูหลาม:

def themethod():
    yield 5

for foo in themethod():
    print foo

แม้ว่าหลักการจะแตกต่างกัน แต่ผลลัพธ์ก็คล้ายคลึงกันอย่างยอดเยี่ยม

Ruby สนับสนุนการเขียนโปรแกรมสไตล์การทำงาน (เหมือนท่อ) ได้ง่ายขึ้น

myList.map(&:description).reject(&:empty?).join("\n")

งูหลาม:

descriptions = (f.description() for f in mylist)
"\n".join(filter(len, descriptions))

Python มีเครื่องกำเนิดไฟฟ้าในตัว (ซึ่งใช้เหมือนบล็อก Ruby ดังที่ระบุไว้ข้างต้น)

Python มีการสนับสนุนสำหรับเครื่องกำเนิดไฟฟ้าในภาษา ใน Ruby 1.8 คุณสามารถใช้โมดูลเครื่องกำเนิดไฟฟ้าซึ่งใช้การดำเนินการต่อเพื่อสร้างเครื่องกำเนิดไฟฟ้าจากบล็อก หรือคุณสามารถใช้บล็อก / proc / lambda! ยิ่งไปกว่านั้นใน Ruby 1.9 Fibers คือและสามารถใช้เป็นเครื่องกำเนิดไฟฟ้าและคลาส Enumerator เป็นเครื่องกำเนิดไฟฟ้าในตัว4

docs.python.orgมีตัวอย่างของตัวสร้างนี้:

def reverse(data):
    for index in range(len(data)-1, -1, -1):
        yield data[index]

ตัดกันนี้ด้วยตัวอย่างบล็อกด้านบน

Python มีการจัดการพื้นที่ชื่อที่ยืดหยุ่น

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

ใน Python ไฟล์เป็นโมดูลและคุณสามารถนำเข้าชื่อที่มีอยู่ด้วยfrom themodule import *ซึ่งจะทำให้เนมสเปซสกปรกหากคุณต้องการ แต่คุณยังสามารถนำเข้าเฉพาะชื่อที่เลือกด้วยfrom themodule import aname, anotherหรือคุณสามารถimport themoduleเข้าถึงชื่อthemodule.anameได้อย่างง่ายดาย หากคุณต้องการระดับเพิ่มเติมในเนมสเปซของคุณคุณสามารถมีแพ็คเกจซึ่งเป็นไดเรกทอรีที่มีโมดูลและ__init__.pyไฟล์

Python มีเอกสารประกอบ

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

def frobnicate(bar):
    """frobnicate takes a bar and frobnicates it

       >>> bar = Bar()
       >>> bar.is_frobnicated()
       False
       >>> frobnicate(bar)
       >>> bar.is_frobnicated()
       True
    """

รูบี้เทียบเท่าของ javadocs และอยู่เหนือวิธีแทนที่จะอยู่ข้างใน พวกเขาสามารถดึงข้อมูลได้จากรันไทม์จากไฟล์โดยใช้การใช้ตัวอย่าง # method_ source_location

Python มีหลายมรดก

Ruby ไม่ ("กับจุดประสงค์" - ดูเว็บไซต์ของ Ruby ดูที่นี่ทำอย่างไรใน Ruby ) มันนำแนวคิดของโมดูลมาใช้ใหม่เป็นคลาสนามธรรม

Python มี list / dict comprehensions

งูหลาม:

res = [x*x for x in range(1, 10)]

ทับทิม:

res = (0..9).map { |x| x * x }

งูหลาม:

>>> (x*x for x in range(10))
<generator object <genexpr> at 0xb7c1ccd4>
>>> list(_)
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

ทับทิม:

p = proc { |x| x * x }
(0..9).map(&p)

Python 2.7+ :

>>> {x:str(y*y) for x,y in {1:2, 3:4}.items()}
{1: '4', 3: '16'}

ทับทิม:

>> Hash[{1=>2, 3=>4}.map{|x,y| [x,(y*y).to_s]}]
=> {1=>"4", 3=>"16"}

Python มีผู้ตกแต่ง

สิ่งที่คล้ายกับมัณฑนากรสามารถสร้างได้ใน Ruby และยังสามารถเป็นที่ถกเถียงกันอยู่ว่าพวกเขาไม่จำเป็นเท่าใน Python

ความแตกต่างของไวยากรณ์

Ruby ต้องการ "end" หรือ "}" เพื่อปิดขอบเขตทั้งหมดในขณะที่ Python ใช้ white-space เท่านั้น ทับทิมมีความพยายามครั้งล่าสุดในการอนุญาตให้เว้นวรรคเยื้องเท่านั้นhttp://github.com/michaeledgar/se ราบรื่น


2
สำหรับมรดกหลาย ๆ ตัวการพูดว่า "Ruby ไม่ได้" นั้นไม่ตรงข้ามกัน ฉันไม่สามารถคิดถึงสิ่งที่คุณสามารถทำได้ใน Python ด้วยการสืบทอดหลายอย่างที่คุณไม่สามารถทำได้ในทับทิมกับโมดูล / "การสืบทอดมรดก" (ก็จะยิ่งพิสูจน์ได้ว่ารวมทั้งโมดูลเพียงธรรมดาเป็นมรดกหลาย.)
โลแกน Capaldo

2
ที่คุณสามารถทำสิ่งเดียวกันด้วยวิธีอื่นเป็นอาร์กิวเมนต์ที่ไม่ถือ คุณสามารถทำทุกอย่างได้ที่นี่ด้วยวิธีอื่น และเนื่องจากโมดูลไม่ใช่คลาสจึงไม่ใช่การสืบทอดหลายอย่าง คุณยินดีที่จะมีส่วนร่วมในตัวอย่างโค้ดเกี่ยวกับวิธีการทำงานใน Pythons ที่สืบทอดหลาย ๆ ครั้งเทียบกับโมดูล Rubys
Lennart Regebro

3
โมดูลไม่ใช่คลาส แต่คลาสเป็นโมดูล % ruby ​​-e 'p Class <โมดูล' เป็นจริง
Logan Capaldo

8
-1 น่าเสียดายที่คำถามนี้พลาดไปกับเป้าหมายและความแตกต่างส่วนใหญ่ไม่ได้ต่างกันเลย
อคติ

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

คำตอบ:


34

ทับทิมมีแนวคิดของบล็อกซึ่งโดยทั่วไปแล้วจะเป็นน้ำตาลซินแทคติครอบส่วนของโค้ด พวกเขาเป็นวิธีในการสร้างการปิดและส่งพวกเขาไปยังวิธีอื่นซึ่งอาจหรือไม่อาจใช้บล็อก บล็อกสามารถเรียกใช้ในภายหลังผ่านyieldคำสั่ง

ตัวอย่างเช่นคำจำกัดความง่ายๆของeachวิธีการArrayอาจเป็นสิ่งที่ชอบ:

class Array
  def each
    for i in self  
      yield(i)     # If a block has been passed, control will be passed here.
    end  
  end  
end  

จากนั้นคุณสามารถเรียกใช้เช่นนี้:

# Add five to each element.
[1, 2, 3, 4].each{ |e| puts e + 5 }
> [6, 7, 8, 9]

Python มีฟังก์ชัน / closures / lambdas ที่ไม่ระบุตัวตน แต่มันไม่มีการบล็อกเลยเพราะมันขาดน้ำตาล syntactic ที่มีประโยชน์ อย่างไรก็ตามมีอย่างน้อยหนึ่งวิธีที่จะทำให้เป็นโฆษณาแบบเฉพาะกิจ ดูตัวอย่างเช่นที่นี่


6
@ เลนนาร์ท: นอกเหนือจากตัวอย่างของคุณแล้วเพียงแค่พูดด้วยความกลัวมันเป็นความผิดทางไวยากรณ์เช่นกัน

2
@unbeknow: A ถูกต้อง แต่ถ้ามันเป็นฟังก์ชั่นแทนที่จะเป็นงานพิมพ์มันก็น่าจะใช้ได้ ในงูหลาม 3 งานนี้: [พิมพ์ (e + 5) สำหรับ e ใน [1,2,3,4]] และเมื่อพูดถึงความน่ากลัวฉันคิดว่ารหัสทับทิมด้านบนนั้นน่ากลัวดังนั้นมันจึงเป็นอัตนัยอย่างชัดเจนและไม่ใช่ ส่วนหนึ่งของคำถามนี้ @ จอห์นฉันไม่ได้บอกว่ามันเทียบเท่าฉันกำลังบอกว่ามันไม่ชัดเจนว่าสิ่งที่แตกต่างจากตัวอย่างของคุณ @Bastien ไม่ แต่คุณสามารถทำสิ่งที่คล้ายกันไม่ได้หมายความว่าพวกเขาเหมือนกัน ความแตกต่างที่นี่ควรมีการระบุไว้แม้ว่าจะมีวิธีในการทำ
Lennart Regebro

22
ฉันเป็นโปรแกรมเมอร์ Python ฉันต้องการดูตัวอย่างว่าทับทิมบล็อกช่วยให้คุณเขียนสิ่งที่กระชับหรือสวยงามกว่า Python ได้อย่างไรเพราะมันไม่มีบล็อก ตัวอย่างของคุณสามารถเขียนได้: สำหรับฉันใน [1, 2, 3, 4]: print (i + 5) มันไม่ได้ใช้บล๊อก แต่อย่างกระชับและสวยงามเช่นเดียวกับทับทิมแต่ละตัวอย่าง
Manuel Ceron

10
@Manuel, procs มีประโยชน์สำหรับการแนบ functors กับโครงสร้างข้อมูลที่ไม่สำคัญ (ต้นไม้, กราฟ ... ) ซึ่งไม่สามารถ 'for-looped' และดังนั้นจึงจำเป็นต้องมีตัววนซ้ำพิเศษในการตัดทอน บล็อกซึ่งเป็น procs นิรนามให้คุณใช้ functor ในนิพจน์เดียว (เทียบกับ define แล้วนำไปใช้) ซึ่งเพิ่มความเร็วในกระบวนการเข้ารหัสและชี้แจงเจตนาอย่างชัดเจน เช่นถ้าคุณกำลังสร้างโครงสร้างข้อมูลกราฟคุณสามารถกำหนดหนึ่ง 'แต่ละ' iterator แล้ว mixin Enumerable ซึ่งจะทำให้คุณสามารถเข้าถึง iterators นับสิบทันที (เรียงลำดับทั้งหมดหรือไม่? grep) ตอนนี้คุณเรียกบล็อก ...
อคติ

4
@RommeDeSerieux เพราะมันต้องการชื่อในภาษา! ยิ่งไปกว่านั้นมันเป็นฟังก์ชั่นวัตถุไม่ใช่ฟังก์ชั่น ลองดูที่ Ruby Docs: "ออบเจ็กต์ Proc เป็นบล็อกของโค้ดที่ผูกกับชุดของตัวแปรในเครื่อง" ดังนั้น Proc นิรนามจึงเป็นเพียงบล็อกและแน่นอนไม่ใช่ฟังก์ชัน!
อคติ

28

ตัวอย่าง Python

ฟังก์ชั่นเป็นตัวแปรชั้นหนึ่งใน Python คุณสามารถประกาศฟังก์ชันส่งผ่านมันเป็นวัตถุและเขียนทับมัน:

def func(): print "hello"
def another_func(f): f()
another_func(func)

def func2(): print "goodbye"
func = func2

นี่เป็นคุณสมบัติพื้นฐานของภาษาสคริปต์สมัยใหม่ JavaScript และ Lua ก็ทำเช่นนี้เช่นกัน Ruby ไม่ปฏิบัติหน้าที่ด้วยวิธีนี้ การตั้งชื่อฟังก์ชั่นเรียกมันว่า

แน่นอนมีวิธีที่จะทำสิ่งเหล่านี้ใน Ruby แต่พวกเขาไม่ได้ดำเนินการชั้นหนึ่ง ตัวอย่างเช่นคุณสามารถห่อฟังก์ชันด้วย Proc.new เพื่อใช้เป็นตัวแปร - แต่จากนั้นจะไม่มีฟังก์ชันอีกต่อไป มันเป็นวัตถุที่มีวิธี "โทร"

ฟังก์ชั่นของรูบี้ไม่ใช่วัตถุชั้นหนึ่ง

ฟังก์ชั่นทับทิมไม่ใช่วัตถุชั้นหนึ่ง ฟังก์ชั่นจะต้องห่อด้วยวัตถุเพื่อส่งผ่าน วัตถุที่เป็นผลลัพธ์ไม่สามารถปฏิบัติได้เหมือนฟังก์ชั่น ไม่สามารถกำหนดฟังก์ชั่นในระดับเฟิร์สคลาสได้ ต้องเรียกใช้ฟังก์ชันในวัตถุคอนเทนเนอร์แทนเพื่อปรับเปลี่ยน

def func; p "Hello" end
def another_func(f); method(f)[] end
another_func(:func)      # => "Hello"

def func2; print "Goodbye!"
self.class.send(:define_method, :func, method(:func2))
func                     # => "Goodbye!"

method(:func).owner      # => Object
func                     # => "Goodbye!"
self.func                # => "Goodbye!"    

8
คุณสับสนมาก วัตถุชั้นแรกที่ได้รับมอบหมายโดยการโอน: ไม่ได้โดยโทรx = y self.class.send(:define_method, :func, method(:func2))"ตัวอย่างตัวอย่าง" ของคุณแสดงให้เห็นว่าหน้าที่ของรูบี้ไม่ได้อยู่ในอันดับหนึ่ง หากคุณไม่เห็นด้วยอย่าลังเลที่จะโพสต์คำตอบของคุณเอง อย่าติดความสับสนในตัวฉัน
Glenn Maynard

7
สิ่งต่าง ๆ ที่กำหนดโดยdef ... endทับทิมไม่ใช่ฟังก์ชั่น เป็นวิธีการ (วิธีที่คุณกำหนดจากKernel) วิธีการสามารถหลุด (ใช้#methodวิธีการ) ซึ่งเป็นวัตถุ สิ่งที่ใกล้เคียงที่สุดของทับทิมที่มีต่อฟังก์ชั่นก็คือProcอินสแตนซ์ซึ่งก็เป็นวัตถุเช่นกัน นอกจากนี้ยังมีไวยากรณ์พิเศษสำหรับการส่งผ่านโทรกลับเดียวProcกับวิธีการเช่นเดียวกับจอห์น Feminella กล่าวถึงในคำตอบของเขา
rampion

4
@Glenn: ฉันได้สิ่งที่คุณพูด แต่ฉันจะพูดคลุมเครือกับการยืนยันว่าฟังก์ชันการกำหนดนิยามใหม่ของรูบี้ - วิธีการเป็นแนวคิดเชิงความหมายแยกต่างหาก หากคุณต้องการเล่นเกมนิยามรหัสที่สำคัญที่สุดคือขั้นตอนไม่ใช่ฟังก์ชั่น ฉันไม่ได้พยายามที่จะยากมันเป็นเพียงแค่ฉันเชื่อว่าคำจำกัดความและความถูกต้องมีความสำคัญ ฉันจะยอมรับว่าการจัดการUnboundMethodสามารถเป็น PITA, สรรพสินค้า
rampion

5
@ Glenn: ความงามอยู่ในสายตาของคนดู อย่างไรก็ตามวิธีการเป็นวัตถุชั้นหนึ่งโดยการปฏิบัติตามคำนิยาม (ในกรณีนี้ฉันหมายถึงคำนิยามของวิกิพีเดีย) บางทีคุณมีคำจำกัดความอื่น ๆ ของชั้นหนึ่ง? พวกเขาจำเป็นต้องใช้บัตร Platinum Frequent Flier เพื่อชนชั้นหนึ่งหรือไม่?
อคติ

4
@Glenn ตรวจสอบส่วนคำถามที่พบบ่อย SO "คนอื่นสามารถแก้ไขข้อมูลของฉันได้!" - นี่คือ Wiki ชุมชน
bias

26

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

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

ย้อนกลับคำในสายนี้:

sentence = "backwards is sentence This"

เมื่อคุณคิดว่าจะทำอย่างไรคุณจะทำสิ่งต่อไปนี้:

  1. แบ่งประโยคออกเป็นคำ
  2. กลับคำ
  3. รวมคำกลับเข้าไปในสตริงอีกครั้ง

ใน Ruby คุณจะทำสิ่งนี้:

sentence.split.reverse.join ' '

อย่างที่คุณคิดเกี่ยวกับมันในลำดับเดียวกันหนึ่งวิธีการโทรหลังจากที่อื่น

ในไพ ธ อนมันจะมีลักษณะดังนี้:

" ".join(reversed(sentence.split()))

มันไม่ยากที่จะเข้าใจ แต่มันก็ไม่เหมือนกัน หัวเรื่อง (ประโยค) ถูกฝังอยู่ตรงกลาง การดำเนินการเป็นการผสมผสานระหว่างฟังก์ชั่นและวิธีการของวัตถุ นี่เป็นตัวอย่างเล็ก ๆ น้อย ๆ แต่มีตัวอย่างหนึ่งที่ค้นพบตัวอย่างที่แตกต่างกันมากมายเมื่อทำงานกับและเข้าใจทับทิมโดยเฉพาะอย่างยิ่งในงานที่ไม่สำคัญ


1
ฉันเห็นด้วย. เมื่อฉันเขียนมันดูเหมือนว่าทับทิมจะไหลตามธรรมชาติดังนั้น "zenlike" จึงเป็นคำที่ดี
คนดีบุก

18

Python มีความคิดว่า "พวกเราทุกคนเป็นผู้ใหญ่ที่นี่" ดังนั้นคุณจะพบว่ารูบีมีสิ่งต่าง ๆ เช่นค่าคงที่ในขณะที่ไพ ธ อนไม่ได้ (แม้ว่าค่าคงที่ของรูบี้จะส่งสัญญาณเตือนเท่านั้น) วิธีคิดของ Python คือถ้าคุณต้องการทำให้บางอย่างคงที่คุณควรใส่ชื่อตัวแปรในตัวพิมพ์ใหญ่ทั้งหมดและไม่เปลี่ยน

ตัวอย่างเช่น Ruby:

>> PI = 3.14
=> 3.14
>> PI += 1
(irb):2: warning: already initialized constant PI
=> 4.14

งูหลาม:

>>> PI = 3.14
>>> PI += 1
>>> PI
4.1400000000000006

19
ฮา .. นี่แค่เตือนฉันว่าอย่างน้อยใน python 2 * คุณสามารถทำ "True, False = False, True" ... ฉันเชื่อว่าพวกเขาได้แก้ไขอย่างถูกต้องใน python 3.0 ... นั่นเป็นสิ่งที่คุณควรป้องกันได้จากการทำ
Tom

11
โดยส่วนตัวแล้วฉันชอบแนวทางที่เข้มงวดซึ่งบังคับใช้โดยภาษาเพราะทำให้รหัสทั้งหมดเขียนด้วยภาษานั้นสอดคล้องกัน มันบังคับให้คุณทำตามแนวทางและนักพัฒนาที่อ่านรหัสของคุณสามารถบอกได้ทันทีว่ามีอะไรเกิดขึ้น ในขณะที่ตัวเขียน Python ส่วนใหญ่ใช้ "style" ทั่วไปเหมือนกันฉันได้เห็นความไม่แน่นอนที่ค่อนข้างใหญ่ซึ่งเป็นไปไม่ได้ใน Ruby
Sasha Chedygov

8
@bias - ฉันไม่แน่ใจว่าทำไมคุณกำลัง downvoting ฉัน คำตอบนี้ไม่เห็นด้วยหรือไม่เห็นด้วยกับวิธีการทำสิ่งหลาม มันเป็นเพียงคำแถลงความจริง
เจสันเบเกอร์

13
@ Jason "พวกเราทุกคนเป็นผู้ใหญ่ที่นี่" เป็นคำแถลงข้อเท็จจริงหรือไม่? ฉันต้องการเรียกว่าความเห็นที่ล้อมรอบสถานที่ดังนั้นการลงคะแนน
อคติ

7
@bias - การพูดว่า "พวกเราทุกคนเป็นผู้ใหญ่ที่นี่" ไม่ได้มีความหมายอะไร มันเป็นคำขวัญ Python ที่ไม่เป็นทางการซึ่งฉันเชื่อว่าเป็นคำอธิบายที่ดีที่สุดที่นี่: mail.python.org/pipermail/tutor/2003-October/025932.html
Evan Porter

18

คุณสามารถนำเข้าเฉพาะฟังก์ชั่นจากโมดูลใน Python ใน Ruby คุณนำเข้ารายการวิธีการทั้งหมด คุณสามารถ "นำเข้า" พวกเขาใน Ruby แต่ไม่ใช่ทุกอย่างเกี่ยวกับ

แก้ไข:

มารับโมดูล Ruby นี้กัน:


module Whatever
  def method1
  end

  def method2
  end
end

หากคุณรวมไว้ในรหัสของคุณ:


include Whatever

คุณจะเห็นว่ามีการเพิ่มทั้งmethod1และmethod2ในเนมสเปซของคุณ คุณไม่สามารถนำเข้าเพียงmethod1 คุณนำเข้าทั้งคู่หรือไม่นำเข้าเลย ใน Python คุณสามารถนำเข้าเฉพาะวิธีการที่คุณเลือก หากนี่จะมีชื่อบางทีมันอาจจะเรียกว่าการนำเข้าแบบเลือก?


2
โอ้ใช่! Python ชอบเนมสเปซ ไม่ใช่อย่างนั้นใน Ruby? คุณไม่ได้import bla; bla.foo()อยู่ในทับทิม?
Lennart Regebro

2
คุณสามารถนำเข้าเฉพาะฟังก์ชั่น a ไม่ใช่ฟังก์ชั่นทั้งหมดที่อยู่ภายใน ตัวอย่างเช่นหากคุณรวมโมดูล Ruby ที่ประกาศฟังก์ชันที่ไม่คงที่ 3 รายการคุณจะได้รับสิ่งเหล่านี้ทั้งหมดรวมอยู่ในเนมสเปซของคุณ ในไพ ธ อนคุณต้องเขียนจากโมดูลนำเข้า *
Geo

6
นั่นไม่ได้นำไปสู่ความยุ่งเหยิง namespace จำนวนมาก?
Lennart Regebro

1
ฉันคิดว่ามันทำ นั่นคือสิ่งที่ฉันเกลียดเกี่ยวกับโมดูลทับทิม
Geo

8
Ruby ไม่มีระบบโมดูลในความหมายเดียวกับหลาม ต้องใช้งานโดยทั่วไปเป็นข้อความรวมกับการตรวจสอบบางอย่างสำหรับการรวม dupilicate อบคุณสามารถ (ab) ใช้โมดูลเป็น namespaces แต่moduleจริงๆแล้วเป็นบิตของการเรียกชื่อผิด โมดูลมีพื้นซองเรียนnew, allocateวิธีการ พวกเขาทำงานได้ดีที่สุดเป็นวิธีแชร์รหัสตามระดับ / วัตถุไม่ใช่กลไกสำหรับการแบ่งพาร์ติชันไลบรารีหรือใช้รหัสร่วมกันระหว่างโปรแกรม
Logan Capaldo

16

จากเว็บไซต์ของ Ruby :

ความคล้ายคลึงกันเช่นเดียวกับ Python ใน Ruby ...

  • มีพรอมต์แบบโต้ตอบ (เรียกว่า IRB)
  • คุณสามารถอ่านเอกสารบนบรรทัดคำสั่ง (ด้วยคำสั่ง ri แทน pydoc)
  • ไม่มีการยกเลิกบรรทัดพิเศษ (ยกเว้นการขึ้นบรรทัดใหม่ตามปกติ)
  • ตัวอักษรสตริงสามารถขยายหลายบรรทัดเช่นสตริงที่ยกมาสามของ Python
  • วงเล็บมีไว้สำหรับรายการและเครื่องหมายวงเล็บมีไว้สำหรับ dicts (ซึ่งใน Ruby เรียกว่า "hash")
  • อาร์เรย์ทำงานเหมือนกัน (การเพิ่มพวกมันทำให้เกิดอาร์เรย์ที่ยาวหนึ่งอัน แต่การเขียนพวกมันเช่นนี้a3 = [ a1, a2 ]จะทำให้คุณมีอาร์เรย์ของอาร์เรย์)
  • วัตถุถูกพิมพ์อย่างรุนแรงและแบบไดนามิก
  • ทุกอย่างเป็นวัตถุและตัวแปรเป็นเพียงการอ้างอิงถึงวัตถุ
  • แม้ว่าคำหลักจะแตกต่างกันเล็กน้อย แต่ข้อยกเว้นทำงานเหมือนกัน
  • คุณมีเครื่องมือ doc แบบฝังตัว (Ruby's เรียกว่า rdoc)

ความแตกต่างจาก Python ใน Ruby ...

  • สตริงไม่แน่นอน
  • คุณสามารถสร้างค่าคงที่ (ตัวแปรที่ค่าที่คุณไม่ต้องการเปลี่ยน)
  • มีบางกรณีที่มีการบังคับใช้ (เช่นชื่อคลาสเริ่มต้นด้วยตัวพิมพ์ใหญ่ตัวแปรเริ่มต้นด้วยตัวอักษรพิมพ์เล็ก)
  • มีรายการคอนเทนเนอร์หนึ่งชนิดเท่านั้น (Array) และสามารถเปลี่ยนแปลงได้
  • สตริงที่มีเครื่องหมายอัญประกาศคู่อนุญาตให้ใช้ลำดับการยกเว้น (เช่น \ t) และไวยากรณ์ "การแทนที่นิพจน์" พิเศษ (ซึ่งอนุญาตให้คุณแทรกผลลัพธ์ของนิพจน์ Ruby ลงในสตริงอื่น ๆ โดยตรงโดยไม่ต้อง "เพิ่ม" + "สตริง" + "ด้วยกัน") . สตริงที่ยกมาเดี่ยวเป็นเหมือน "p rawon" ของ Python
  • ไม่มีคลาส "สไตล์ใหม่" และ "สไตล์เก่า" เพียงชนิดเดียว
  • คุณไม่เคยเข้าถึงคุณลักษณะโดยตรง ด้วย Ruby มันเป็นการเรียกใช้เมธอดทั้งหมด
  • วงเล็บสำหรับการเรียกเมธอดเป็นทางเลือก
  • มีรัฐเอกชนและการป้องกันในการบังคับใช้การเข้าถึงแทน _voluntary_ underscore __convention__
  • ใช้“ mixin” แทนการสืบทอดหลายครั้ง
  • คุณสามารถเพิ่มหรือปรับเปลี่ยนวิธีการเรียนในตัว ทั้งสองภาษาให้คุณเปิดและแก้ไขคลาสได้ทุกเมื่อ แต่ Python ป้องกันการแก้ไขบิวด์อิน - Ruby ไม่ได้
  • คุณมีจริงและเท็จแทนจริงและเท็จ (และไม่มีแทนไม่มี)
  • เมื่อทดสอบเพื่อความจริงเฉพาะเท็จและไม่มีค่าประเมินเป็นค่าเท็จ ทุกสิ่งทุกอย่างเป็นจริง (รวมถึง 0, 0.0, "" และ [])
  • มันเป็น Elif แทน Elif
  • มันต้องการแทนการนำเข้า มิฉะนั้นแม้ว่าการใช้งานจะเหมือนกัน
  • ความคิดเห็นสไตล์ปกติในบรรทัดเหนือสิ่งต่างๆ (แทนที่จะเป็นเอกสารด้านล่าง) ใช้สำหรับสร้างเอกสาร
  • มีทางลัดจำนวนมากที่ให้คุณจำได้มากกว่า แต่คุณเรียนรู้ได้อย่างรวดเร็ว พวกเขามักจะทำให้ Ruby สนุกและมีประสิทธิภาพมาก

2
"มันต้องการแทนการนำเข้ามิฉะนั้นการใช้งานก็เหมือนกัน" ดูเหมือนว่าจะไม่ถูกต้องสมบูรณ์
Glenjamin

นอกจากนี้ยังมีชุดใน Ruby ที่ผู้คนไม่ค่อยใช้ แต่มันถูกสร้างขึ้นมาดังนั้นฉันสามารถพูดได้ว่า stuff_in_backpack = Set.new; stuff_in_backpack << "คอมพิวเตอร์"; stuff_in_backpack << "รองเท้า"; # และชุดจะเก็บค่าทั้งหมดโดยไม่รับประกันการสั่งซื้อ
zachaysan

12

สิ่งที่ Ruby มีมากกว่า Python คือความสามารถด้านภาษาสคริปต์ ภาษาสคริปต์ในบริบทนี้มีความหมายที่จะใช้สำหรับ "รหัสกาว" ในเชลล์สคริปต์และการจัดการข้อความทั่วไป

ส่วนใหญ่ใช้ร่วมกับ Perl นิพจน์ทั่วไปในตัวระดับเฟิร์สคลาส $ -Variables ตัวเลือกบรรทัดคำสั่งที่มีประโยชน์เช่น Perl (-a, -e) เป็นต้น

ร่วมกับไวยากรณ์สั้น ๆ แต่ยังเป็น epxressive มันเหมาะสำหรับงานประเภทนี้

Python สำหรับฉันเป็นภาษาทางธุรกิจที่มีการพิมพ์แบบไดนามิกมากขึ้นซึ่งง่ายต่อการเรียนรู้และมีไวยากรณ์ที่เรียบร้อย ไม่ใช่ "เท่ห์" เหมือนทับทิม แต่เรียบร้อย สิ่งที่หลามมีมากกว่าทับทิมสำหรับฉันคือการผูกจำนวนมากมายสำหรับ libs อื่น ๆ การเชื่อมโยงกับ Qt และ libs GUI อื่น ๆ , ไลบรารีเกมสนับสนุนจำนวนมากและและและ ทับทิมมีน้อยกว่ามาก ในขณะที่การเชื่อมโยงที่ใช้กันมากเช่นฐานข้อมูลมีคุณภาพดีฉันพบ libs เฉพาะที่จะได้รับการสนับสนุนที่ดีกว่าใน Python แม้ว่าสำหรับไลบรารีเดียวกันจะมีการเชื่อม Ruby ด้วย

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


1
คำถามจากคนที่ยังไม่รู้จัก Ruby: คุณหมายถึงอะไร "$ -Variables"? คุณหมายถึงตัวแปรทั่วโลกหรือไม่ ถ้าเป็นเช่นนั้นใน Python ตัวแปรที่กำหนดในโมดูลนอกคลาสหรือฟังก์ชั่นนั้นเป็นค่าโกลบอล ถ้าไม่ - ความแตกต่างคืออะไร?
Anon

1
อานนท์: หากคุณประกาศตัวแปร $ ที่ใดก็ได้ในรหัสมันเป็นแบบโกลบอลเนื่องจากส่วนนำหน้า ดังนั้นมันไม่สำคัญว่ามันจะถูกกำหนดไว้ที่ใดเสมอว่าเป็นโลกและเป็นที่รู้จักเช่นนี้เสมอ
Robert K

8
ไม่แน่นอนจริง ๆ แล้วฉันหมายถึงตัวแปรที่กำหนดไว้ล่วงหน้าเช่น $ _, $ 1 ฯลฯ ซึ่งเต็มไปด้วยค่าโดยอัตโนมัติด้วยทับทิม $ _ เป็นบรรทัดสุดท้ายที่อ่าน $ 1, $ 2, ฯลฯ เป็นการจับคู่นิพจน์ทั่วไปจากการแข่งขันครั้งสุดท้าย ดูที่นี่สำหรับรายการทั้งหมด: zenspider.com/Language/Ruby/QuickRef.html#17โดยทั่วไปแล้วมันเป็นแฮ็คสำหรับสคริปต์ขนาดกะทัดรัด คุณสามารถรับข้อมูลทั้งหมดผ่านการโทรด้วย API ได้เช่นกัน แต่การใช้ $ ตัวแปรจะมีความกระชับมากกว่า ตัวแปรประเภทนี้ไม่เหมาะกับสไตล์ของ Python พวกเขาจงใจทิ้งมันไว้
haffax

ขอบคุณสำหรับการเชื่อมโยง zenspider - มองหาบางสิ่งเช่นนั้นเพื่อความรู้สึกที่รวดเร็ว (ไม่ใช่การสอน) สำหรับ Ruby
Anon

12

ฉันไม่คิดว่า "Ruby มี X และ Python ไม่ได้ในขณะที่ Python มี Y และ Ruby ไม่" เป็นวิธีที่มีประโยชน์มากที่สุดในการดู เป็นภาษาที่ค่อนข้างคล้ายกันมีความสามารถในการแบ่งปันมากมาย

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


5
ฉันยอมรับว่า lambdas มีขอบเขต จำกัด และไม่มีประโยชน์ในหลายกรณี อย่างไรก็ตามฉันไม่คิดว่ามันยุติธรรมที่จะบอกว่าโปรแกรมเมอร์ Python หลีกเลี่ยงพวกเขาเช่นภัยพิบัติ
เจสันเบเกอร์

1
ฉันยอมรับว่า lambdas มักใช้กับ Python เช่นเดียวกับแผนที่ตัวกรองลด ความแตกต่างครั้งใหญ่น่าจะเป็นว่า Lambdas ของ Python จำกัด เฉพาะการแสดงออกในขณะที่บล็อก Ruby สามารถเป็นแบบหลายบรรทัดและเกี่ยวข้องกับข้อความ ความประทับใจโดยทั่วไปของฉันจากสิ่งที่ฉันได้อ่านเกี่ยวกับ Ruby ก็คือคุณสมบัตินี้ทำให้ Rubyists ใช้วิธี DSL ในขณะที่ Pythonistas มีแนวโน้มที่จะสร้าง API ขึ้นมา ข้อมูลของฉันใน Ruby ยังคงตื้นมาก
Anon

2
@ เลนนาร์ท: มีการใช้บล็อกหลายบรรทัดในรูบี - บ่อยกว่าที่ฉันเห็นแลมบ์ดาใช้ในรหัส Python รหัส idiomatic สำหรับตัวอย่างที่พบให้ดูที่info.michael-simons.eu/2007/08/06/rails-respond_to-method
Chuck

1
@ เลนนาร์ท: ไม่มันไม่ได้ใช้ผลตอบแทน (อัตราผลตอบแทนของรูบี้แตกต่างอย่างสิ้นเชิงจากอยู่ดี ธ - มันไม่กลับเครื่องกำเนิดไฟฟ้า.) for format in respond_to()มันจะไม่เป็นความหมายที่จะเขียน respond_toวิธีไม่กลับอะไรที่มีความหมาย - มันก็ตอบสนองต่อการร้องขอ HTTP ปัจจุบัน doในrespond_to doเป็นจุดเริ่มต้นของบล็อกที่ ในบล็อกนั้นเราพูดคุยกับวัตถุชั่วคราว (ติดป้ายไว้formatในตัวอย่างนี้) ซึ่งใช้ DSL ขั้นพื้นฐานมากสำหรับการตอบสนองต่อคำขอ HTTP
Chuck

3
คุณสามารถ 'mixin Enumerable' กับเครื่องกำเนิดไฟฟ้าและรับ iterators ใหม่และยอดเยี่ยม 30 ทันที คุณต้องดูภาษาโดยรวมก่อนที่คุณจะเข้าใจว่าเหตุใดบล็อก / Procs จึงยอดเยี่ยม
อคติ

12

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

แต่สิ่งที่เกี่ยวกับเรื่องนี้:

คุณสามารถทำอะไรได้อย่างไพเราะและดีใน Python ที่ไม่สามารถทำได้ใน Ruby ด้วยความงามและวิศวกรรมที่ดีเช่นนั้นหรือในทางกลับกัน

นั่นอาจจะน่าสนใจกว่าการเปรียบเทียบคุณสมบัติเพียงอย่างเดียว


ความคิดเห็นที่ดีที่สุด ยัง +1 ของฉัน
nawfal

11

Python มีไวยากรณ์บิวด์อินอย่างชัดเจนสำหรับ list-comprehenions และ generators โดยที่ใน Ruby คุณจะใช้ map และ code blocks

เปรียบเทียบ

list = [ x*x for x in range(1, 10) ]

ถึง

res = (1..10).map{ |x| x*x }

ความเข้าใจในรายการไม่ใช่Python ธรรมดาอย่างไร และมีฟังก์ชั่นแผนที่ใน Python ด้วย
SilentGhost

แต่ไม่มีไวยากรณ์ความเข้าใจในรายการใน Ruby
Dario

Python: res = map (แลมบ์ดา x: x * x, ช่วง (1,10))
GogaRieger

Python:res=map(2 .__rpow__, range(1,10))
John La Rooy

11

"ตัวแปรที่เริ่มต้นด้วยอักษรตัวใหญ่กลายเป็นค่าคงที่และไม่สามารถแก้ไขได้"

ไม่ถูกต้อง. พวกเขาสามารถ.

คุณจะได้รับคำเตือนถ้าทำเท่านั้น


2
หากภาษาให้คำเตือนสำหรับการดำเนินการมันเป็นความคิดของฉันว่าคุณเป็นอย่างดีสามารถพิจารณาการดำเนินการ "เป็นไปไม่ได้" สิ่งอื่นใดคือความบ้าคลั่ง
porgarmingduod

11

ค่อนข้างมากในด้านโครงสร้างพื้นฐาน:

  • Python มีการรวมที่ดีขึ้นกับ C ++ (ผ่านสิ่งต่างๆเช่นBoost.Python , SIPและPy ++ ) กว่า Ruby ซึ่งตัวเลือกที่ดูเหมือนจะเขียนโดยตรงกับ Ruby interpreter API (ซึ่งคุณสามารถทำได้กับ Python เช่นกันแน่นอน แต่ในทั้งสองกรณีการทำเช่นนี้อยู่ในระดับต่ำน่าเบื่อและเกิดข้อผิดพลาดได้ง่าย) หรือใช้ SWIG (ซึ่งในขณะที่มันใช้งานได้และยอดเยี่ยมมากถ้าคุณต้องการรองรับหลายภาษาไม่ดีเท่า Boost.Python หรือ SIP คุณกำลังมองหาการผูก C ++) โดยเฉพาะ

  • Python มีสภาพแวดล้อมของเว็บแอปพลิเคชั่นจำนวนมาก (Django, Pylons / Turbogears, web.py, อย่างน้อยครึ่งโหล) ในขณะที่ Ruby (มีประสิทธิภาพ) มีหนึ่ง: Rails (เฟรมเวิร์กเว็บ Ruby อื่น ๆ มีอยู่ แต่ดูเหมือนว่าจะมีความยากลำบากในการได้รับแรงฉุดมากกับ Rails) แง่มุมนี้ดีหรือไม่ดี? ยากที่จะพูดและอาจเป็นอัตวิสัย ฉันสามารถจินตนาการได้อย่างง่ายดายว่าข้อโต้แย้งว่าสถานการณ์ไพ ธ อนนั้นดีกว่าและสถานการณ์รูบีนั้นดีกว่า

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


7
จุดที่สองของคุณนั้นผิดไปมากที่สุด คุณควรเริ่มต้นโดยดูที่ Rack and Sinatra
Max Ogden

6
ฉันทราบอย่างชัดเจนว่าสแต็คของ Rails อื่นนั้นมีอยู่; ฉันไม่คิดว่าจะมีใครใช้พวกเขาจริง ๆ การตรวจสอบ Sinatra and Rack ไม่ได้เปลี่ยนความประทับใจนั้นอย่างแน่นอน คุณคิดว่าจริง ๆ แล้วพูดซินาตร้า (94 คำถามรวมดังนั้น) หรือตั้งแคมป์ (รวม 2 คำถามดังนั้น) หรืออื่น ๆ จริง ๆ มีฐานผู้ใช้ / ชุมชนจริงหรือไม่ ส่วนใหญ่ไม่มีผู้ใช้งานจริงเท่าที่ฉันจะบอกได้ เปรียบเทียบกับ Django (4K +) หรือ Rails (7K +) หรือแม้กระทั่ง web.py สำหรับเรื่องนั้น
Jack Lloyd

1
ซินาตร้าค่อนข้างได้รับความนิยมสำหรับงานที่แตกต่างและมีน้ำหนักเบาเนื่องจาก DSL มันใช้น้อยกว่าเพราะ MVC ของรถไฟให้มากกว่านี้ Rails สร้างขึ้นจริงบน Rack - นั่นคือสิ่งที่ทำให้ Phusion Passenger เป็นไปได้
ทางเลือก

11

คัดลอก / วางอย่างไม่ลดละจาก: Alex Martelliตอบคำถาม" ดีกว่าเกี่ยวกับ Ruby กว่า Python "จากรายการส่งเมลcomp.lang.python

18 ส.ค. 2003, 10:50 น. Erik Max Francis เขียนว่า:

"Brandon J. Van Every" เขียน:

มีอะไรดีกว่า Ruby มากกว่า Python ฉันแน่ใจว่ามีบางอย่าง มันคืออะไร?

มันจะไม่สมเหตุสมผลกว่าหรือที่จะถามคน Ruby กับเรื่องนี้มากกว่าคน Python

อาจหรืออาจจะไม่ขึ้นอยู่กับจุดประสงค์ของคน - ตัวอย่างเช่นถ้าวัตถุประสงค์ของคนนั้นรวมถึง "การศึกษาทางสังคมวิทยา" ของชุมชน Python การตั้งคำถามกับชุมชนนั้นน่าจะพิสูจน์การเปิดเผยข้อมูลเกี่ยวกับมันได้มากกว่าที่อื่น :-)

โดยส่วนตัวฉันดีใจที่มีโอกาสได้ติดตามการสอน Ruby หนึ่งวันของ Dave Thomas ที่ OSCON ล่าสุด ด้านล่างแผ่นไม้อัดบางส่วนของความแตกต่างทางไวยากรณ์ฉันพบว่า Ruby และ Python คล้ายกันอย่างน่าอัศจรรย์ - ถ้าฉันคำนวณต้นไม้ที่ครอบคลุมน้อยที่สุดในภาษาชุดใด ๆ ฉันค่อนข้างมั่นใจว่า Python และ Ruby จะเป็นสองใบแรกที่รวมเข้าด้วยกัน โหนดระดับกลาง :-)

แน่นอนว่าฉันเบื่อหน่ายในรูบีของการพิมพ์ "สิ้นสุด" โง่ ๆ ในตอนท้ายของแต่ละบล็อก (แทนที่จะเป็นเพียงการผูกมัด) - แต่จากนั้นฉันจะหลีกเลี่ยงการพิมพ์โง่เง่า ':' ซึ่ง Python ต้องการที่ เริ่มต้นของแต่ละบล็อกเพื่อให้เป็นเกือบล้าง :-) ความแตกต่างทางไวยากรณ์อื่น ๆ เช่น '@foo' กับ 'self.foo' หรือความสำคัญที่สูงขึ้นของเคสใน Ruby vs Python เป็นเรื่องเกี่ยวกับฉัน

คนอื่น ๆ ไม่ต้องสงสัยเลยว่าพวกเขาเลือกภาษาการเขียนโปรแกรมในประเด็นดังกล่าวและพวกเขาสร้างการอภิปรายที่ร้อนแรงที่สุด - แต่สำหรับฉันนั่นเป็นเพียงตัวอย่างหนึ่งของกฎหมายของพาร์คินสันในการดำเนินการ (จำนวนการอภิปรายปัญหา ความสำคัญจริง)

แก้ไข (โดย AM 6/19/2010 11:45): นี่เป็นที่รู้จักกันในนาม "ระบายสี the bikeshed" (หรือเรียกสั้น ๆ ว่า "bikeshedding") - การอ้างอิงคือไปยัง Northcote Parkinson อีกครั้งซึ่งให้การอภิปราย ในสิ่งที่สีในการวาด bikeshed "เป็นตัวอย่างทั่วไปของ" การอภิปรายร้อนในหัวข้อเล็กน้อย " (สิ้นสุดของแก้ไข)

หนึ่งความแตกต่างทางไวยากรณ์ที่ฉันพบว่าสำคัญและเป็นที่โปรดปรานของ Python - แต่คนอื่น ๆ จะไม่สงสัยเลยว่าสิ่งที่ตรงกันข้าม - คือ "คุณเรียกฟังก์ชันที่ไม่มีพารามิเตอร์" ได้อย่างไร ใน Python (เหมือนใน C) ในการเรียกใช้ฟังก์ชันคุณจะใช้ "ตัวดำเนินการโทร" เสมอ - วงเล็บท้ายหลังวัตถุที่คุณกำลังเรียก (ภายในวงเล็บเหล่านั้นจะไป args ที่คุณกำลังผ่านสาย - ถ้า คุณไม่ผ่าน args แล้ววงเล็บจะว่างเปล่า) ใบนี้พูดถึงเพียง ใด ๆวัตถุที่ไม่มีโอเปอเรเตอร์ที่เกี่ยวข้องเป็นความหมายเพียงการอ้างอิงไปยังวัตถุ - ในบริบทใด ๆ โดยไม่มีกรณีพิเศษข้อยกเว้นกฎเฉพาะกิจและอื่น ๆ ใน Ruby (เหมือนใน Pascal) ในการเรียกใช้งานฟังก์ชั่นที่มีอาร์กิวเมนต์คุณจะผ่าน args (โดยปกติจะอยู่ในวงเล็บแม้ว่าจะไม่ใช่กรณีที่คงเส้นคงวา) - แต่ถ้าฟังก์ชั่นไม่มี args แล้วเพียงแค่พูดถึงฟังก์ชั่น สิ่งนี้อาจตอบสนองความคาดหวังของหลาย ๆ คน (อย่างน้อยก็ไม่ต้องสงสัยเลยว่าผู้ที่เคยมีประสบการณ์ในการเขียนโปรแกรมมาก่อนเท่านั้นคือ Pascal หรือภาษาอื่น ๆ ที่มี "การเรียกโดยนัย" เช่น Visual Basic) - แต่สำหรับฉันแล้ว การกล่าวถึงวัตถุเพียงอย่างเดียวอาจหมายถึงการอ้างอิงไปยังวัตถุหรือการเรียกวัตถุขึ้นอยู่กับประเภทของวัตถุ - และในกรณีเหล่านั้นที่ฉันสามารถ ' ไม่ได้รับการอ้างอิงไปยังวัตถุโดยเพียงกล่าวถึงมันฉันจะต้องใช้อย่างชัดเจน "ให้ฉันอ้างอิงถึงสิ่งนี้อย่าเรียกมันว่า!" ผู้ประกอบการที่ไม่จำเป็นต้องใช้อย่างอื่น ฉันรู้สึกว่าสิ่งนี้ส่งผลกระทบต่อ "ชั้นหนึ่ง" ของฟังก์ชั่น (หรือวิธีการหรือวัตถุที่เรียกได้อื่น ๆ ) และความเป็นไปได้ของการเปลี่ยนวัตถุอย่างราบรื่น ดังนั้นสำหรับฉันความแตกต่างทางไวยากรณ์ที่เฉพาะเจาะจงนี้เป็นเครื่องหมายสีดำที่ร้ายแรงต่อ Ruby - แต่ฉันเข้าใจว่าทำไมคนอื่นถึงทำอย่างอื่นแม้ว่าฉันจะไม่เห็นด้วยกับพวกเขา :-) ฟังก์ชั่น (หรือวิธีการหรือวัตถุ callable อื่น ๆ ) และความเป็นไปได้ของการแลกเปลี่ยนวัตถุได้อย่างราบรื่น ดังนั้นสำหรับฉันความแตกต่างทางไวยากรณ์ที่เฉพาะเจาะจงนี้เป็นเครื่องหมายสีดำที่ร้ายแรงต่อ Ruby - แต่ฉันเข้าใจว่าทำไมคนอื่นถึงทำอย่างอื่นแม้ว่าฉันจะไม่เห็นด้วยกับพวกเขา :-) ฟังก์ชั่น (หรือวิธีการหรือวัตถุ callable อื่น ๆ ) และความเป็นไปได้ของการแลกเปลี่ยนวัตถุได้อย่างราบรื่น ดังนั้นสำหรับฉันความแตกต่างทางไวยากรณ์ที่เฉพาะเจาะจงนี้เป็นเครื่องหมายสีดำที่ร้ายแรงต่อ Ruby - แต่ฉันเข้าใจว่าทำไมคนอื่นถึงทำอย่างอื่นแม้ว่าฉันจะไม่เห็นด้วยกับพวกเขา :-)

ด้านล่างไวยากรณ์เราได้รับความแตกต่างที่สำคัญในความหมายเบื้องต้น - ตัวอย่างเช่นสตริงใน Ruby เป็นวัตถุที่ไม่แน่นอน (เช่นใน C ++) ในขณะที่ Python ไม่สามารถเปลี่ยนแปลงได้ (เช่นใน Java หรือฉันเชื่อว่า C #) อีกครั้งคนที่ตัดสินโดยสิ่งที่พวกเขาคุ้นเคยอยู่แล้วอาจคิดว่านี่เป็นข้อดีสำหรับ Ruby (เว้นแต่พวกเขาจะคุ้นเคยกับ Java หรือ C # แน่นอน :-) ฉันฉันคิดว่าสตริงที่ไม่เปลี่ยนรูปนั้นเป็นความคิดที่ยอดเยี่ยม (และฉันไม่แปลกใจเลยที่ Java, ฉันคิดอย่างอิสระ, คิดใหม่แนวคิดที่มีอยู่แล้วใน Python) แม้ว่าฉันจะไม่รังเกียจว่าจะมี "บัฟเฟอร์สตริงที่ไม่แน่นอน" (และอันที่หนึ่งควรมีความสะดวกในการใช้งานที่ดีกว่า "สตริงบัฟเฟอร์" ของ Java); และฉันไม่ได้ตัดสินเรื่องนี้เนื่องจากความคุ้นเคย - ก่อนเรียน Java ข้อมูลทั้งหมดเปลี่ยนแปลงไม่ได้ทุกภาษาที่ฉันรู้ว่ามีสายอักขระที่เปลี่ยนแปลงไม่ได้ - แต่เมื่อฉันเห็นแนวคิดสตริงที่ไม่เปลี่ยนรูปแบบครั้งแรกใน Java (ซึ่งฉันเรียนรู้ได้ดีก่อนที่ฉันจะเรียนรู้ Python) มันทำให้ฉันยอดเยี่ยมทันที การอ้างอิงความหมายของภาษาการเขียนโปรแกรมระดับที่สูงขึ้น (ตรงข้ามกับความหมายของค่าที่เหมาะสมที่สุดกับภาษาที่อยู่ใกล้กับเครื่องและอยู่ไกลจากแอปพลิเคชันเช่น C) ที่มีสตริงเป็นแบบเฟิร์สคลาสในตัว สำคัญ) ประเภทข้อมูล

Ruby มีข้อได้เปรียบบางประการในความหมายเบื้องต้น - ตัวอย่างเช่นการลบ Python "list vs tuples" ที่แตกต่างอย่างมาก แต่ส่วนใหญ่คะแนน (อย่างที่ฉันเก็บไว้ด้วยความเรียบง่ายบวกที่ใหญ่และบอบบางความแตกต่างที่ชาญฉลาดที่น่าทึ่งลบ) เป็นกับทับทิม (เช่นมีทั้งช่วงปิดและครึ่งเปิดด้วยสัญลักษณ์ a .. b และ a .. .b [ใครต้องการที่จะอ้างว่าเป็นที่ชัดเจนหรือไม่ -)] ที่โง่ - IMHO แน่นอน!) อีกครั้งผู้ที่พิจารณาว่ามีสิ่งที่คล้ายกัน แต่มีความแตกต่างอย่างละเอียดที่แกนกลางของภาษามากกว่าจะเป็นลบซึ่งแน่นอนว่าจะนับ "วิธีอื่น ๆ " จากวิธีที่ฉันนับ :-)

อย่าเข้าใจผิดโดยการเปรียบเทียบเหล่านี้กับการคิดว่าทั้งสองภาษานั้นมี ความสำคัญมากแตกต่างใจคุณ พวกเขาไม่ได้ แต่ถ้าฉันขอให้เปรียบเทียบ "capelli d'angelo" กับ "spaghettini" หลังจากชี้ให้เห็นว่าพาสต้าทั้งสองชนิดนี้ไม่เกี่ยวกับใครเลยและไม่สามารถแยกแยะได้ในอาหารจานใดที่คุณอาจต้องการเตรียมไว้อย่างหลีกเลี่ยงไม่ได้ เมื่อต้องการย้ายเข้าสู่การตรวจด้วยกล้องจุลทรรศน์ว่าความยาวและเส้นผ่าศูนย์กลางแตกต่างกันอย่างไรการสิ้นสุดของเส้นเกลียวจะเรียวในกรณีหนึ่งและไม่ใช่ในอีกกรณีและอื่น ๆ - เพื่อลองอธิบายว่าทำไมฉันเองควรมี capelli 'angelo เป็นพาสต้าในน้ำซุปชนิดใดก็ได้ แต่ชอบ spaghettini เป็น pastasciutta ที่จะไปพร้อมกับซอสที่เหมาะสมสำหรับรูปแบบพาสต้าบาง ๆ ที่ยาว (น้ำมันมะกอก, กระเทียมสับ, พริกแดงสับและปลาแอนโชวี่อย่างประณีต) ตัวอย่างเช่น - แต่ถ้าคุณหั่นกระเทียมและพริกแทนที่จะหั่นเป็นชิ้นเล็ก ๆ คุณควรเลือกสปาเก็ตตี้ซาวด์มากกว่าสปาเก็ตตินีที่บางกว่าและควรที่จะละทิ้งความเจ็บปวดและเพิ่มโหระพาฤดูใบไม้ผลิแทน [ หรือแม้กระทั่ง - ฉันเป็นคนนอกรีต ... ! - แสงสะระแหน่ ... ] ใบไม้ - ในช่วงเวลาสุดท้ายก่อนที่จะเสิร์ฟจาน) อุ๊ปส์ขอโทษมันแสดงให้เห็นว่าฉันกำลังเดินทางไปต่างประเทศและไม่เคยมีพาสต้าสักพักฉันเดา แต่การเปรียบเทียบก็ยังค่อนข้างดี! -) - แสงสะระแหน่ ... ] ใบไม้ - ในช่วงเวลาสุดท้ายก่อนที่จะเสิร์ฟจาน) อุ๊ปส์ขอโทษมันแสดงให้เห็นว่าฉันกำลังเดินทางไปต่างประเทศและไม่เคยมีพาสต้าสักพักฉันเดา แต่การเปรียบเทียบก็ยังค่อนข้างดี! -) - แสงสะระแหน่ ... ] ใบไม้ - ในช่วงเวลาสุดท้ายก่อนที่จะเสิร์ฟจาน) อุ๊ปส์ขอโทษมันแสดงให้เห็นว่าฉันกำลังเดินทางไปต่างประเทศและไม่เคยมีพาสต้าสักพักฉันเดา แต่การเปรียบเทียบก็ยังค่อนข้างดี! -)

ดังนั้นกลับไปที่ Python และ Ruby เรามาถึงสอง biggies (ในแง่ของภาษาที่เหมาะสม - ออกจากห้องสมุดและอุปกรณ์เสริมที่สำคัญอื่น ๆ เช่นเครื่องมือและสภาพแวดล้อม, วิธีการฝัง / ขยายแต่ละภาษา ฯลฯ ฯลฯ จาก สำหรับตอนนี้ - พวกเขาจะไม่นำไปใช้กับการใช้งานทั้งหมดของแต่ละภาษาอย่างไรก็ตาม Jython vs Classic Python เป็นการนำภาษา Python มาใช้งานสองแบบ!):

  1. iterators ของ Ruby และ codeblocks เทียบกับ iterators และ Python ของ Python;

  2. TOTAL ของ Ruby "ไดนามิก" ที่ไม่มีการควบคุมรวมถึงความสามารถใน
    การ "เปิด" คลาสที่มีอยู่ใด ๆ รวมถึงคลาสที่มีอยู่ทั้งหมดและเปลี่ยนพฤติกรรมในเวลาทำงาน - เทียบกับไดนามิกที่กว้างใหญ่ แต่มีขอบเขตของ Python ซึ่งไม่เคยเปลี่ยนพฤติกรรมของที่มีอยู่ คลาสที่มีอยู่แล้วและอินสแตนซ์ของมัน

โดยส่วนตัวแล้วฉันคิดว่า1การล้าง (ความแตกต่างนั้นลึกมากจนฉันสามารถเห็นคนที่เกลียดการเข้าใกล้และกราบไหว้คนอื่นได้ง่าย แต่ในส่วนตัวของฉัน และ2ประเด็นที่สำคัญ - สิ่งหนึ่งที่ทำให้ทับทิมเหมาะกว่าสำหรับ "การซ่อมแซม" แต่ BUT Python นั้นเหมาะกว่าสำหรับการใช้งานในแอปพลิเคชันขนาดใหญ่ มันตลกในทางหนึ่งเพราะทั้งสองภาษานั้นมีพลังมากกว่าคนอื่น ๆ ส่วนใหญ่ในที่สุดความแตกต่างที่สำคัญระหว่างพวกเขาจาก POV ของฉันควรขึ้นอยู่กับสิ่งนั้น - ทับทิม "ไปสิบเอ็ด" ในเรื่องนี้ (อ้างอิง นี่คือ "Spinal Tap" แน่นอน) ในทับทิมฉันสามารถทำมันได้ ! นั่นคือฉันสามารถเปลี่ยนคลาสสตริงในตัวเพื่อให้ a = "Hello World" b = "hello world" ถ้า == b พิมพ์ "เท่ากัน! \ n" พิมพ์อื่น "แตกต่างกัน! \ n" สิ้นสุดจะพิมพ์ " เท่ากัน". ในไพ ธ อนไม่มีทางที่ฉันจะทำได้ สำหรับวัตถุประสงค์ของ metaprogramming การนำกรอบงานทดลองมาใช้และความสามารถที่น่าทึ่งของ Ruby นั้นเป็นไปอย่างยิ่งยวด อุทธรณ์ แต่ - ถ้าเรากำลังพูดถึงแอพพลิเคชั่นขนาดใหญ่ที่พัฒนาโดยคนจำนวนมากและได้รับการบำรุงรักษามากขึ้นรวมถึงห้องสมุดทุกประเภทจากแหล่งที่หลากหลายและต้องการที่จะไปผลิตในไซต์ลูกค้า ... ดีฉันไม่ต้องการ ภาษาที่มีพลังมากขอบคุณมาก ฉันเกลียดความคิดที่ว่าห้องสมุดบางแห่งจะทำลายสิ่งที่ไม่เกี่ยวข้องอื่น ๆ โดยไม่เจตนาซึ่งขึ้นอยู่กับสตริงเหล่านั้นแตกต่าง - นั่นคือ "ช่อง" ที่ซ่อนอยู่ลึกและลึกระหว่างส่วนของโค้ดที่ LOOK แยกออกมาและควรแยกจากกัน การเขียนโปรแกรมขนาดใหญ่ โดยการปล่อยให้โมดูลใด ๆ ส่งผลกระทบต่อพฤติกรรมของ "ความลับ" อื่น ๆ ความสามารถในการกลายพันธุ์ความหมายของชนิดในตัวเป็นเพียงแนวคิดที่ไม่ดีสำหรับการเขียนโปรแกรมแอปพลิเคชันการผลิต

ถ้าฉันต้องใช้ Ruby สำหรับแอปพลิเคชั่นขนาดใหญ่ฉันจะพยายามใช้ข้อ จำกัด ของการเข้ารหัสสไตล์การทดสอบจำนวนมาก (จะเรียกใช้ซ้ำเมื่อใดก็ตามที่มีการเปลี่ยนแปลงใด ๆ - แม้สิ่งที่ควรจะไม่เกี่ยวข้องทั้งหมด ... ) และทำนองเดียวกัน เพื่อห้ามการใช้งานคุณสมบัติภาษานี้ แต่การไม่มีคุณสมบัติในตอนแรกดีกว่าในความคิดของฉัน - เช่นเดียวกับ Python จะเป็นภาษาที่ดียิ่งขึ้นสำหรับการเขียนโปรแกรมประยุกต์หากจำนวนบิวด์อินบางตัวอาจ "ถูกลบ" ดังนั้นฉันจึงรู้ว่า เช่น len ("ciao") คือ 4 (แทนที่จะต้องกังวลว่าใครบางคนเปลี่ยนการผูกชื่อ 'len' ในโมดูลbuiltins ... ) หรือไม่ ฉันหวังว่าในที่สุด Python จะ "ตอกย้ำ" โครงสร้างภายในของมัน

แต่ปัญหาของปัญหาเล็กน้อยเนื่องจากการรีบิวด์อินใหม่นั้นค่อนข้างที่จะเลิกใช้แล้วรวมถึงการฝึกฝนที่หายากใน Python ใน Ruby มันทำให้ฉันรู้สึกว่าสำคัญ - เช่นเดียวกับ สิ่งอำนวยความสะดวกที่มีประสิทธิภาพมากเกินไปของภาษาอื่น ๆ (เช่นพูด Dylan) นำเสนอความเสี่ยงที่คล้ายกันในความคิดเห็นของฉัน (ฉันหวังว่า Python จะไม่ได้รับระบบมาโครที่ทรงพลังเช่นนี้ สิ่งที่ดึงดูดใจของ "ให้ผู้คนนิยามภาษาเล็ก ๆ ของตัวเองโดยเฉพาะโดเมนที่ฝังตัวในภาษาของตัวเอง" - มันจะ IMHO ทำให้ Python มีประโยชน์ที่ยอดเยี่ยมสำหรับการเขียนโปรแกรมแอปพลิเคชั่นโดยการนำเสนอ " สิงสถิตอยู่ในหัวใจของโปรแกรมเมอร์ทุกคน ... )

อเล็กซ์


9

บางคนจาก:

http://www.ruby-lang.org/en/documentation/ruby-from-other-languages/to-ruby-from-python/

(หากฉันได้ทำการตรวจสอบสิ่งที่ผิดหรือสิ่งเหล่านี้มีการเปลี่ยนแปลงที่ด้านทับทิมตั้งแต่หน้านั้นได้รับการปรับปรุงใครบางคนรู้สึกอิสระที่จะแก้ไข ... )

สตริงไม่แน่นอนใน Ruby ไม่ใช่ใน Python (โดยที่สตริงใหม่จะถูกสร้างโดย "เปลี่ยนแปลง")

Ruby มีการบังคับใช้ตัวพิมพ์เล็กบางตัว Python ไม่มี

Python มีทั้งรายการและสิ่งอันดับ (รายการที่ไม่เปลี่ยนรูป) Ruby มีอาร์เรย์ที่สอดคล้องกับรายการ Python แต่ไม่มีตัวแปรที่เปลี่ยนแปลงไม่ได้ของมัน

ใน Python คุณสามารถเข้าถึงคุณสมบัติของวัตถุได้โดยตรง ในรูบีมันจะผ่านวิธีการเสมอ

ใน Ruby วงเล็บสำหรับการเรียกใช้เมธอดเป็นทางเลือก แต่ไม่ใช่ใน Python

Ruby มีสาธารณะเป็นส่วนตัวและได้รับการปกป้องในการบังคับใช้การเข้าถึงแทนที่จะเป็นแบบแผนของ Python ในการใช้เครื่องหมายขีดล่างและการสร้างชื่อ

Python มีหลายมรดก Ruby มี "มิกซ์อิน"

และลิงค์อื่นที่เกี่ยวข้องมาก:

http://c2.com/cgi/wiki?PythonVsRuby

โดยเฉพาะอย่างยิ่งลิงก์ไปยังอีกอันที่ดีโดย Alex Martelliผู้ซึ่งโพสต์สิ่งดีๆมากมายไว้ที่ SO:

http://groups.google.com/group/comp.lang.python/msg/028422d707512283


1
ในทับทิมคุณสามารถตรึงอาร์เรย์ของคุณเพื่อเปลี่ยนเป็นสิ่งที่ไม่เปลี่ยนรูปแบบได้
user163365

โพสต์ที่ยอดเยี่ยมโดย Alex Martelli :)
Skilldrick

8

ฉันไม่แน่ใจในสิ่งนี้ดังนั้นฉันจึงเพิ่มเป็นคำตอบก่อน

Python ใช้เมธอด unbound เป็นฟังก์ชัน

ซึ่งหมายความว่าคุณสามารถเรียกวิธีการอย่างใดอย่างหนึ่งเช่นtheobject.themethod()หรือโดยTheClass.themethod(anobject)หรือโดยการ

แก้ไข: แม้ว่าความแตกต่างระหว่างวิธีการและฟังก์ชั่นมีขนาดเล็กใน Python และไม่มีอยู่ใน Python 3 แต่ก็ไม่ได้มีอยู่ใน Ruby เพียงเพราะ Ruby ไม่มีฟังก์ชั่น เมื่อคุณกำหนดฟังก์ชั่นจริง ๆ แล้วคุณกำลังกำหนดวิธีการบนวัตถุ

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


Ruby ไม่มีฟังก์ชั่นเลย ที่กล่าวว่าTheClass.instance_method(:themethod).bind(anobject).callจะเป็นทับทิมเทียบเท่า
Logan Capaldo

โอ้ มีคลาสหลักเวทมนต์บางอย่างเมื่อคุณกำหนดฟังก์ชั่นที่ไม่ได้อยู่ในชั้นเรียนที่ชัดเจน?
Lennart Regebro

Objectใช่วิธีการที่กำหนดไว้ในระดับชั้นนำที่มีวิธีการของภาคเอกชน
Logan Capaldo

1
FWIW มันก็ดูเหมือนว่าในหลาม, ฟังก์ชั่นและวิธีการที่เป็นจริงชนิดเดียวกันและพฤติกรรมที่แตกต่างกันของพวกเขามาจากอธิบาย: users.rcn.com/python/download/...
Bastien Léonard

1
แต่ถ้าคุณผูกมันไว้กับวัตถุมันก็ไม่ได้หลุด ดุจ :-) และมันก็เป็นสิ่งเดียวกันใน Python เช่นกัน เพียงว่าทับทิมไม่ได้มีฟังก์ชั่น และนั่นหมายความว่าคำสั่งของฉันถูกต้อง คุณสามารถเรียกเมธอด unbound ราวกับว่ามันเป็นฟังก์ชันใน Python และนั่นก็มีประโยชน์จริง ๆ นั่นหมายถึงตัวอย่างเช่นคุณสามารถเรียกวิธีการที่กำหนดไว้ในคลาสบนวัตถุที่ไม่มีคลาสนั้นซึ่งบางครั้งก็มีประโยชน์
Lennart Regebro

7

ฉันต้องการพูดถึง Python descriptor API ที่อนุญาตให้ปรับแต่ง "การสื่อสาร" แบบ object-to-attribute นอกจากนี้ยังเป็นที่น่าสังเกตว่าใน Python หนึ่งมีอิสระที่จะใช้โปรโตคอลทางเลือกผ่านการแทนที่ค่าเริ่มต้นที่กำหนดผ่านการใช้งานเริ่มต้นของ__getattribute__วิธีการ ให้ฉันให้รายละเอียดเพิ่มเติมเกี่ยวกับข้างต้น อธิบายชั้นเรียนปกติกับ__get__, __set__และ / หรือ__delete__วิธีการ เมื่อล่ามพบสิ่งที่ต้องการanObj.anAttrจะดำเนินการดังต่อไปนี้:

  • __getattribute__วิธีการของanObjถูกเรียก
  • __getattribute__ ดึงวัตถุ anAttr จากคลาส dict
  • มันจะตรวจสอบว่า abAttr วัตถุมี__get__, __set__หรือ__delete__วัตถุ callable
  • บริบท (เช่นผู้เรียกวัตถุหรือคลาสและค่าแทนที่จะเป็นหลังถ้าเรามี setter) จะถูกส่งผ่านไปยังวัตถุที่เรียกได้
  • ผลลัพธ์จะถูกส่งคืน

ดังที่ได้กล่าวมานี้เป็นพฤติกรรมเริ่มต้น หนึ่งมีอิสระที่จะเปลี่ยนโปรโตคอลโดยการนำมาใช้ใหม่__getattribute__ใหม่

เทคนิคนี้มีพลังมากกว่านักตกแต่ง


6

Ruby มีการสนับสนุนการสร้างต่อเนื่องโดยใช้ callccสนับสนุนต่อเนื่องโดยใช้

ดังนั้นคุณสามารถใช้สิ่งที่ยอดเยี่ยมเช่นผู้ควบคุมงาน


ฉันหวังว่าฉันเข้าใจ callcc คุณสามารถให้สถานการณ์แอปพลิเคชันทางโลกมากกว่าผู้ดำเนินการที่ไม่ชัดเจนของ McCarthy เพื่อชื่นชมความน่าสนใจของมันได้หรือไม่? ฉันหมายถึงบางสิ่งในโลกแห่งความเป็นจริงไม่ใช่สิ่ง CS ที่ขี้ขลาด?!
ThomasH

"สิ่งที่ Funky CS" เป็นของจริง ใช้เวลาในการเรียนรู้: intertwingly.net/blog/2005/04/13/Continuations-for-Curmudgeons
Stephen Eilert


5

Python มีเอกสารและทับทิมไม่ ... หรือถ้าไม่มีก็ไม่สามารถเข้าถึงได้ง่ายเหมือนกับในภาษาไพ ธ อน

ps ถ้าฉันผิดโปรดสวยออกจากตัวอย่าง? ฉันมีวิธีแก้ปัญหาที่ฉันสามารถ monkeypatch เข้าเรียนได้ค่อนข้างง่าย แต่ฉันต้องการให้ docstring มีคุณลักษณะในลักษณะ "เนทีฟ"


3
ไม่มี docstring แต่ไม่มี RDoc ใช่แล้วไม่ใช่เข้าถึงได้ง่าย แต่ไม่ซ่อน 100%
โอมาร์ Qureshi

Ruby ไม่ใช้ docstrings มันทำเอกสารในวิธีที่แตกต่าง
Chuck

1
Omar: ใช่ฉันรู้เกี่ยวกับ rdoc แต่ afaik พวกเขาไม่ได้ "เข้าถึงได้" เหมือนกับเอกสารของงูใหญ่ ตัวอย่างเช่นถ้าฉันมีชั้นเรียนและฉันต้องการที่จะเอาท์พุทเอกสาร rdoc จากภายในชั้นงานมันสวยงานหนัก สิ่งที่ฉันได้ทำคือฉันสร้างเอกสาร ri ซึ่งฉันพยายามรักษา up2date แล้วดึงข้อมูลนั้นมาจาก vi แน่นอนไม่ถึงระดับเดียวกับ docstrings หลาม ..
rasjani

สามารถใช้เอกสารประกอบเพื่อสอนได้ มีอะไรแบบนั้นสำหรับทับทิมหรือไม่?
Lennart Regebro

2
ใช่มันเรียกว่า "Ruby Doctest" เท่าที่มีความเกี่ยวข้องกับการสอนสิ่งที่สำคัญคือคุณมีเอกสารที่สามารถอ่านได้ที่ไหนสักแห่งที่มีตัวอย่างโค้ดที่ทดสอบได้ - มันไม่ได้สร้างความแตกต่างไม่ว่าจะเป็นในเอกสารหรือในความคิดเห็น
Chuck

5

Ruby มีทีละบรรทัดวนรอบไฟล์อินพุต (แฟล็ก '-n') จาก commandline เพื่อให้สามารถใช้เช่น AWK Ruby หนึ่งซับนี้:

ruby -ne 'END {puts $.}'

จะนับจำนวนบรรทัดเช่น AWK หนึ่งซับ:

awk 'END{print NR}'

Ruby ได้รับฟีเจอร์นี้ผ่าน Perl ซึ่งนำมาจาก AWK เป็นวิธีการดูแลระบบด้วย Perl โดยไม่ต้องเปลี่ยนวิธีการทำสิ่งต่าง ๆ


1
ฉันต้องการเพิ่มว่าการสนับสนุนบรรทัดคำสั่งของ Pyth ค่อนข้างอ่อนแอ นอกจากการวนซ้ำอัตโนมัติที่ขาดหายไปคุณไม่สามารถใส่คำสั่งสองสามคำในหนึ่งบรรทัดและส่งผ่านเป็นอาร์กิวเมนต์บรรทัดคำสั่งแบบสตริงเดียวไปยังล่าม อย่างน้อยฉันก็ไม่ทำเช่นนั้น
ThomasH

แน่นอนคุณสามารถ. แต่คุณจะ (เช่นเดียวกับภาษา otehr ใด ๆ ) จำเป็นต้องใส่ไว้ในเครื่องหมายคำพูด
Lennart Regebro

Python ไม่ได้ถูกใช้งานบน commandline เนื่องจากคุณต้องมีความชัดเจนเกี่ยวกับบางสิ่ง (เช่น sys.stdin) หากคุณต้องการใช้มันในแบบนั้นpython -c "import sys; print len(list(sys.stdin))"
u0b34a0f6ae

5

Ruby มี sigils และ twigils, Python ไม่มี

แก้ไข : และสิ่งหนึ่งที่สำคัญมากที่ฉันลืม (หลังจากทั้งหมดก่อนหน้านี้เป็นเพียงการจุดไฟเล็กน้อย :-p):

Python มีคอมไพเลอร์ JIT ( Psyco ) ซึ่งเป็นภาษาระดับต่ำกว่าที่เห็นได้ชัดสำหรับการเขียนโค้ดที่เร็วขึ้น ( Pyrex ) และความสามารถในการเพิ่มโค้ด C ++ แบบอินไลน์ ( สาน )


จริง แต่นั่นเป็นเพียงไวยากรณ์
Lennart Regebro

6
ถ้าคุณต้องการลงไปที่ถนนนั้น: ทัวริงสมบูรณ์ ทุกอย่างอื่นเป็นเพียงไวยากรณ์
Jörg W Mittag

ใช่และความแตกต่างทางไวยากรณ์ของ importax ;-)
fortran

1
มันสำคัญอย่างไรถ้าคุณเขียน @foo หรือ self.foo
Lennart Regebro

1
@ Jörg: ตกลงเรียกมันว่าอย่างอื่นนอกจาก "ไวยากรณ์" แล้ว ประเด็นก็คือ @foo และ self.foo ทำสิ่งเดียวกันมันไม่ใช่การทำงานของ Ruby และ Python ไม่มี
Lennart Regebro

5

งูเหลือมของฉันเป็นสนิมดังนั้นสิ่งเหล่านี้บางอย่างอาจเป็นงูหลามและฉันก็จำไม่ได้ / ไม่เคยเรียนรู้ตั้งแต่แรก แต่นี่เป็นเพียงไม่กี่อย่างแรกที่ฉันนึกถึง:

ช่องว่าง

Ruby จัดการช่องว่างที่แตกต่างอย่างสิ้นเชิง สำหรับผู้เริ่มคุณไม่จำเป็นต้องเยื้องอะไร (ซึ่งหมายความว่าไม่สำคัญว่าคุณใช้ช่องว่าง 4 หรือ 1 แท็บ) นอกจากนี้ยังทำต่อเนื่องของสายสมาร์ทดังนั้นสิ่งต่อไปนี้ที่ถูกต้อง:

def foo(bar,
        cow)

โดยทั่วไปถ้าคุณลงท้ายด้วยโอเปอเรเตอร์มันจะหาว่าเกิดอะไรขึ้น

mixins

Ruby มีมิกซ์อินซึ่งสามารถขยายอินสแตนซ์แทนคลาสเต็มได้:

module Humor
  def tickle
    "hee, hee!"
  end
end
a = "Grouchy"
a.extend Humor
a.tickle    »   "hee, hee!"

enums

ฉันไม่แน่ใจว่านี่จะเหมือนกับเครื่องกำเนิดไฟฟ้าหรือไม่ แต่เป็นทับทิมทับทิม 1.9 เช่นเดียวกับ enums ดังนั้น

>> enum = (1..4).to_enum
=> #<Enumerator:0x1344a8>

การอ้างอิง: http://blog.nuclearsquid.com/writings/ruby-1-9-what-s-new-what-s-changed

"อาร์กิวเมนต์คำหลัก"

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

def foo(a, b=2, c=3)
  puts "#{a}, #{b}, #{c}"
end
foo(1,3)   >> 1, 3, 3
foo(1,c=5) >> 1, 5, 3
c          >> 5

โปรดทราบว่า c = 5 จะกำหนดตัวแปร c ในขอบเขตการเรียกใช้ค่า 5 และตั้งค่าพารามิเตอร์ b เป็นค่า 5

หรือคุณสามารถทำได้ด้วยแฮชซึ่งแก้ไขปัญหาที่สอง

def foo(a, others)
  others[:b] = 2 unless others.include?(:b)
  others[:c] = 3 unless others.include?(:c)
  puts "#{a}, #{others[:b]}, #{others[:c]}"
end
foo(1,:b=>3) >> 1, 3, 3
foo(1,:c=>5) >> 1, 2, 5

อ้างอิง: คู่มือปฏิบัติของทับทิมกับทับทิม


ตัวอย่างที่สองของคุณ foo (1, c = 5) ไม่ได้ทำในสิ่งที่คุณคิด Ruby ไม่มีพารามิเตอร์ชื่อ
horseyguy

5
งูหลามมีสายนัยต่อเนื่องวงเล็บภายใน(, [หรือ{
u0b34a0f6ae

5

คุณสามารถมีโค้ดในนิยามคลาสได้ทั้ง Ruby และ Python อย่างไรก็ตามใน Ruby คุณมีการอ้างอิงถึงคลาส (ตัวเอง) ใน Python คุณไม่มีการอ้างอิงถึงคลาสเนื่องจากยังไม่ได้กำหนดคลาส

ตัวอย่าง:

class Kaka
  puts self
end

ตนเองในกรณีนี้คือคลาสและรหัสนี้จะพิมพ์ "Kaka" ไม่มีวิธีพิมพ์ชื่อคลาสหรือวิธีอื่นเข้าถึงคลาสจากเนื้อหานิยามคลาสใน Python


คุณช่วยให้รายละเอียดเพิ่มเติม (เช่นรหัส) สำหรับจุดแรกของคุณ?
Loïc Wolff

รหัสตัวอย่างเป็นความคิดที่ดีฉันเสริมว่าแม้ว่ากรณีนี้จะเล็กน้อย
Lennart Regebro

@SilentGhost: ฉันไม่สามารถนึกถึงสิ่งที่ไม่ชัดเจนในตอนนี้ :)
Lennart Regebro

คุณสามารถเข้าถึงชื่อคลาสภายในคลาสใน python: class foo (): def init __ (ตัวเอง): พิมพ์ตัวเอง. class .__ .__ name__
txwikinger

1
@txwikinger: ใช่ แต่ไม่ใช่ภายในร่างกายของคลาสซึ่งถูกดำเนินการในเวลาเดียวกันกับclassข้อความ
Bastien Léonard

4

ไวยากรณ์ไม่ใช่สิ่งเล็ก ๆ น้อย ๆ มันมีผลกระทบโดยตรงกับวิธีที่เราคิด นอกจากนี้ยังมีผลโดยตรงกับกฎที่เราสร้างขึ้นสำหรับระบบที่เราใช้ ตัวอย่างเช่นเรามีลำดับของการดำเนินการเนื่องจากวิธีที่เราเขียนสมการทางคณิตศาสตร์หรือประโยค สัญกรณ์มาตรฐานสำหรับคณิตศาสตร์ทำให้ผู้คนสามารถอ่านได้มากกว่าหนึ่งวิธีและได้คำตอบที่แตกต่างกันตามสมการเดียวกัน หากเราใช้สัญลักษณ์นำหน้าหรือหลังคำนำหน้าเราจะสร้างกฎเพื่อแยกความแตกต่างของตัวเลขที่จะจัดการได้มากกว่าแค่มีกฎสำหรับลำดับการคำนวณค่า

สัญกรณ์มาตรฐานทำให้ชัดเจนว่าตัวเลขที่เรากำลังพูดถึงในขณะที่การสั่งซื้อที่จะคำนวณพวกเขาคลุมเครือ สัญลักษณ์คำนำหน้าและคำนำหน้าหลังทำให้ลำดับที่จะคำนวณธรรมดาในขณะที่ทำให้ตัวเลขที่ไม่ชัดเจน Python จะมี lambdas หลายชั้นอยู่แล้วหากไม่ใช่เพราะความยากลำบากที่เกิดจากช่องว่างทาง syntactic (มีข้อเสนอสำหรับดึงสิ่งนี้ออกโดยไม่จำเป็นต้องเพิ่มตัวคั่นบล็อกอย่างชัดเจน)

ฉันพบว่าการเขียนเงื่อนไขที่ฉันต้องการให้เกิดขึ้นได้ง่ายขึ้นหากเงื่อนไขเป็นเท็จง่ายกว่ามากในการเขียนด้วยคำสั่งเว้นแต่ใน Ruby มากกว่าการสร้างแบบ "if-not" ในทับทิมหรือภาษาอื่น ๆ หากภาษาส่วนใหญ่ที่ผู้คนใช้กันทุกวันนี้มีอำนาจเท่ากันไวยากรณ์ของแต่ละภาษาจะได้รับการพิจารณาว่าเป็นเรื่องเล็กน้อยได้อย่างไร หลังจากคุณสมบัติเฉพาะเช่นบล็อกและกลไกการสืบทอด ฯลฯ ไวยากรณ์เป็นส่วนที่สำคัญที่สุดของภาษาแทบจะไม่เป็นเรื่องผิวเผิน

อะไรที่ผิวเผินคือคุณสมบัติด้านสุนทรียศาสตร์ของความงามที่เรากำหนดให้กับไวยากรณ์ สุนทรียศาสตร์ไม่มีส่วนเกี่ยวข้องกับการรับรู้ของเราทำงานอย่างไรไวยากรณ์ไม่


"ความคิดเห็น" นี้มีสามครั้งตราบเท่าที่สิ่งที่ได้รับอนุญาตในความคิดเห็นโดยไม่คำนึงถึงตัวแทน
Andrew Grimm

ที่จริงดูเหมือนว่าดีเป็นคำตอบสำหรับฉัน ตัดออกบิต "นี่คือความคิดเห็น"
Bill the Lizard

3

ประหลาดใจที่ไม่เห็นสิ่งใดที่กล่าวถึงกลไก "วิธีการหายไป" ของทับทิม ฉันจะยกตัวอย่างวิธีการ find_by _... ใน Rails เป็นตัวอย่างของพลังของคุณสมบัติภาษานั้น ฉันเดาว่าสิ่งที่คล้ายกันสามารถนำไปใช้ใน Python ได้ แต่สำหรับความรู้ของฉันมันไม่ได้มีอยู่ในตัว


Python มีget_attributeซึ่งทำสิ่งเดียวกันกับ Ruby method_missing
mipadi

3
ทำไมนักพัฒนางูหลามได้รับบาดเจ็บเสมอเมื่อทับทิมถูกกล่าวถึงทุกที่? คุณไม่สามารถปฏิเสธได้ว่าสิ่งนี้ไม่เป็นความจริง
aarona

method_missingclass M(): def __getattr__(self, n): return lambda: "Missing! " + n; M().hi()สามารถเทิดทูนในหลามในบางกรณี: อย่างไรก็ตามมีความแตกต่างเล็กน้อยและฉันสงสัยว่ามันเป็นสำนวนใน Python :-)

1
@DJTripleThreat: ฉันปฏิเสธว่าเป็นจริง
Lennart Regebro

3

ความแตกต่างอีกอย่างของ lambdas ระหว่าง Python และ Ruby นั้นแสดงให้เห็นโดยปัญหาของเครื่องสะสม Accumulator พิมพ์ซ้ำที่นี่:

เขียนฟังก์ชั่น foo ที่รับหมายเลข n และส่งคืนฟังก์ชันที่ใช้หมายเลข i และส่งคืนค่า n ที่เพิ่มขึ้นโดย i หมายเหตุ: (a) นั่นคือตัวเลขไม่ใช่จำนวนเต็ม (b) ที่เพิ่มขึ้นไม่ใช่บวก

ใน Ruby คุณสามารถทำสิ่งนี้:

def foo(n)
  lambda {|i| n += i }
end

ใน Python คุณจะต้องสร้างออบเจกต์เพื่อคงสถานะ n:

class foo(object):
    def __init__(self, n):
        self.n = n
    def __call__(self, i):
        self.n += i
        return self.n

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


3
คุณไม่สามารถเพิ่มตัวเลขใน Python ได้ดังนั้นข้อ จำกัด จึงไม่สมเหตุสมผล ในจำนวนไพ ธ อนจะไม่เปลี่ยนรูป ถ้าเราเปลี่ยนเป็น "บวก" แทนคลาสนั้นไม่จำเป็น ดังนั้นสิ่งนี้จึงไม่แสดงให้เห็นถึงความแตกต่างของแลมบ์ดา แต่ความแตกต่างของวิธีการทำงานของตัวเลข นอกเสียจากว่าคุณสร้างคลาสที่ไม่แน่นอน :)
Lennart Regebro

2
ข้อ จำกัด อยู่ที่นั่นเพื่อชี้แจงพฤติกรรมที่ต้องการ ปัญหาที่ขอคือคือ: f = foo (10) f (2) >> 12 f (3) >> 15 ... lambda {| i | n + i} ให้: f = foo (10) f (2) >> 12 f (3) >> 13 ... ตัวเลขนั้นไม่เปลี่ยนรูปใน Ruby เช่นกัน - คุณไม่สามารถพูดได้ 2 + = 1 เช่น และ n + = 1 ใช้ได้ในฟังก์ชั่น Python ทั่วไป แต่ไม่ใช่แลมบ์ดา ดังนั้นมันเป็นเรื่องของ "n" คืออะไรความจริงที่ว่ามันถูกสร้างขึ้นเมื่อฟังก์ชั่นถูกเรียกใช้และแลมบ์ดาเกิดขึ้นที่คุณสามารถทำการมอบหมายในแลมบ์ดา (แทนที่จะเป็นแค่การแสดงออก) และมันสามารถเก็บค่าของ n ผ่านหลายสาย
dormsbee

ฉันไม่คิดว่าคุณต้องไปไกลขนาดนี้ใน Python สามารถกำหนดฟังก์ชั่นภายในฟังก์ชั่นอื่น ๆ def foo(n): def f(i): return n + i return f.
FMc

2
มันยังคงไม่เหมือนเดิมและตัวอย่างของคุณเทียบเท่ากับ Python lambda ในความคิดเห็นด้านบน รุ่น Ruby สร้างแลมบ์ดาซึ่งเก็บสถานะระหว่างการโทร ตัวอย่างที่คุณโพสต์ให้คุณกำหนดค่าเริ่มต้นสำหรับ n แต่ฟังก์ชันที่ foo ส่งคืนจะมีค่าเริ่มต้นเสมอ รุ่นทับทิมเพิ่มขึ้น สมมุติว่า f = foo (10) รุ่น Python: f (1) => 11, f (1) => 11. รุ่น Ruby f.call (1) => 11, f.call (1) => 12.
dormsbee

def foo(n): L=[n] def f(i): L[0] += i return L[0] return f. ใน Python3 คุณสามารถใช้nonlocalคำสำคัญ
jfs

3

หลามได้ตั้งชื่ออาร์กิวเมนต์เป็นตัวเลือก

def func(a, b=2, c=3):
    print a, b, c

>>> func(1)
1 2 3
>>> func(1, c=4)
1 2 4

AFAIK Ruby มีเพียงตำแหน่งอากิวเมนต์เท่านั้นเนื่องจาก b = 2 ในการประกาศฟังก์ชั่นเป็นการส่งผลที่ต่อท้ายเสมอ


3
"Ruby มีเพียงตำแหน่งที่มีข้อโต้แย้งเพราะ b = 2 ในการประกาศฟังก์ชั่นคือการส่งผลกระทบต่อท้าย" เสมอหมายความว่าอย่างไร
horseyguy

3
Dunno คุณอาศัยอยู่บนดาวเคราะห์ดวงใด แต่def my_method(param1, optional = false)ทำงานใน Ruby 1.8.6, 1.8.7 และน่าจะเป็น 1.9!
Robert K

5
หมัดชั่วร้ายและผู้คนที่ยกระดับความคิดเห็นของเขาคุณไม่ได้ดูตัวอย่างที่ใกล้พอ เขาสามารถข้ามbพารามิเตอร์ในการfuncโทรและมันยังคงรักษาค่าเริ่มต้น นั่นคือbเป็นอาร์กิวเมนต์ที่สองในลายเซ็น แต่เขาสามารถข้ามได้โดย prefixing c=พารามิเตอร์ที่สองด้วย Ruby ใช้แฮชเพื่อจำลองสิ่งนี้ แต่มันไม่เหมือนกันทุกประการ
maček

2

Ruby มีเอกสารฝังตัว:

 =begin

 You could use rdoc to generate man pages from this documentation

 =end

5
เอกสารท้ายจะเป็นส่วนหนึ่งของวิธีการ / ชั้นเรียนที่คุณตั้งไว้ ดังนั้นคุณสามารถทำความช่วยเหลือ (ชั้น) และมันจะแสดงให้คุณ docstrings ฯลฯ
Lennart Regebro


2

ใน Ruby เมื่อคุณนำเข้าไฟล์ที่มีความต้องการทุกสิ่งที่กำหนดไว้ในไฟล์นั้นจะสิ้นสุดในเนมสเปซส่วนกลางของคุณ

ด้วยCargoคุณสามารถ " ต้องการห้องสมุดได้โดยไม่ต้องยุ่งกับ namespace ของคุณ "

# foo-1.0.0.rb
class Foo
  VERSION = "1.0.0"
end

# foo-2.0.0.rb
class Foo
  VERSION = "2.0.0"
end
>> Foo1 = นำเข้า ("foo-1.0.0")
>> Foo2 = นำเข้า ("foo-2.0.0")
>> Foo1 :: รุ่น
=> "1.0.0"
>> Foo2 :: รุ่น
=> "2.0.0"

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