Ada banyak diskusi tentang Python vs Ruby, dan saya semua menganggapnya sama sekali tidak membantu, karena mereka semua berbalik mengapa fitur X menyebalkan dalam bahasa Y, atau bahwa bahasa klaim Y tidak memiliki X, meskipun kenyataannya memang demikian. Saya juga tahu persis mengapa saya lebih suka Python, tetapi itu juga subjektif, dan tidak akan membantu siapa pun memilih, karena mereka mungkin tidak memiliki selera yang sama dalam pengembangan seperti saya.
Oleh karena itu, akan menarik untuk membuat daftar perbedaan secara obyektif. Jadi tidak ada "lambda Python menyebalkan". Alih-alih jelaskan apa yang lambda Ruby bisa lakukan yang tidak bisa dilakukan Python. Tidak ada subjektivitas. Kode contoh itu bagus!
Jangan memiliki beberapa perbedaan dalam satu jawaban. Dan pilih yang Anda tahu benar, dan turunkan yang Anda tahu salah (atau subjektif). Selain itu, perbedaan sintaksis juga tidak menarik. Kita tahu Python melakukan indentasi seperti yang dilakukan Ruby dengan tanda kurung dan ujung, dan @ disebut self dalam Python.
PEMBARUAN: Sekarang ini adalah wiki komunitas, jadi kami dapat menambahkan perbedaan besar di sini.
Ruby memiliki referensi kelas di badan kelas
Di Ruby Anda memiliki referensi ke kelas (diri) yang sudah ada di badan kelas. Dengan Python, Anda tidak memiliki referensi ke kelas sampai konstruksi kelas selesai.
Sebuah contoh:
class Kaka
puts self
end
self dalam hal ini adalah kelas, dan kode ini akan mencetak "Kaka". Tidak ada cara untuk mencetak nama kelas atau dengan cara lain mengakses kelas dari badan definisi kelas dengan Python (definisi metode luar).
Semua kelas bisa berubah di Ruby
Ini memungkinkan Anda mengembangkan ekstensi ke kelas inti. Berikut adalah contoh ekstensi rel:
class String
def starts_with?(other)
head = self[0, other.length]
head == other
end
end
Python (bayangkan tidak ada ''.startswith
metode):
def starts_with(s, prefix):
return s[:len(prefix)] == prefix
Anda bisa menggunakannya di urutan apa pun (bukan hanya string). Untuk menggunakannya, Anda harus mengimpornya secara eksplisit misalnya from some_module import starts_with
,.
Ruby memiliki fitur scripting seperti Perl
Ruby memiliki regexps kelas satu, $ -variables, awk / perl baris demi baris input loop dan fitur lain yang membuatnya lebih cocok untuk menulis skrip shell kecil yang munge file teks atau bertindak sebagai kode perekat untuk program lain.
Ruby memiliki kelanjutan kelas satu
Berkat pernyataan callcc. Di Python Anda dapat membuat kelanjutan dengan berbagai teknik, tetapi tidak ada dukungan bawaan untuk bahasa tersebut.
Ruby memiliki blok
Dengan pernyataan "do" Anda dapat membuat fungsi anonim multi-baris di Ruby, yang akan diteruskan sebagai argumen ke metode di depan do, dan dipanggil dari sana. Di Python, Anda akan melakukan ini baik dengan meneruskan metode atau dengan generator.
Rubi:
amethod { |here|
many=lines+of+code
goes(here)
}
Python (blok Ruby sesuai dengan konstruksi berbeda di Python):
with amethod() as here: # `amethod() is a context manager
many=lines+of+code
goes(here)
Atau
for here in amethod(): # `amethod()` is an iterable
many=lines+of+code
goes(here)
Atau
def function(here):
many=lines+of+code
goes(here)
amethod(function) # `function` is a callback
Menariknya, pernyataan kemudahan di Ruby untuk memanggil sebuah blok disebut "yield", yang dalam Python akan membuat generator.
Rubi:
def themethod
yield 5
end
themethod do |foo|
puts foo
end
Python:
def themethod():
yield 5
for foo in themethod():
print foo
Meskipun prinsipnya berbeda, hasilnya sangat mirip.
Ruby mendukung pemrograman gaya fungsional (seperti pipa) dengan lebih mudah
myList.map(&:description).reject(&:empty?).join("\n")
Python:
descriptions = (f.description() for f in mylist)
"\n".join(filter(len, descriptions))
Python memiliki generator bawaan (yang digunakan seperti blok Ruby, seperti disebutkan di atas)
Python memiliki dukungan untuk generator dalam bahasa tersebut. Di Ruby 1.8 Anda dapat menggunakan modul generator yang menggunakan lanjutan untuk membuat generator dari sebuah blok. Atau, Anda bisa menggunakan blok / proc / lambda! Selain itu, di Ruby 1.9 Serat adalah, dan dapat digunakan sebagai, generator, dan kelas Enumerator adalah generator bawaan 4
docs.python.org memiliki contoh generator ini:
def reverse(data):
for index in range(len(data)-1, -1, -1):
yield data[index]
Bandingkan ini dengan contoh blok di atas.
Python memiliki penanganan ruang nama yang fleksibel
Di Ruby, saat Anda mengimpor file dengan require
, semua hal yang ditentukan dalam file itu akan berakhir di namespace global Anda. Ini menyebabkan polusi namespace. Solusi untuk itu adalah modul Ruby. Tetapi jika Anda membuat namespace dengan modul, maka Anda harus menggunakan namespace itu untuk mengakses kelas yang ada di dalamnya.
Dalam Python, file tersebut adalah modul, dan Anda dapat mengimpor nama yang ada di dalamnya from themodule import *
, sehingga mencemari namespace jika Anda mau. Tetapi Anda juga dapat mengimpor nama yang dipilih dengan from themodule import aname, another
atau Anda dapat dengan mudah import themodule
dan kemudian mengakses nama dengan themodule.aname
. Jika Anda ingin lebih banyak level di namespace Anda, Anda dapat memiliki paket, yang merupakan direktori dengan modul dan __init__.py
file.
Python memiliki docstrings
Docstring adalah string yang dilampirkan ke modul, fungsi, dan metode, serta dapat diintrospeksi saat runtime. Ini membantu untuk membuat hal-hal seperti perintah bantuan dan dokumentasi otomatis.
def frobnicate(bar):
"""frobnicate takes a bar and frobnicates it
>>> bar = Bar()
>>> bar.is_frobnicated()
False
>>> frobnicate(bar)
>>> bar.is_frobnicated()
True
"""
Yang setara dengan Ruby mirip dengan javadocs, dan terletak di atas metode, bukan di dalamnya. Mereka bisa diambil pada waktu proses dari file dengan menggunakan metode 1.9 Metode # source_location digunakan
Python memiliki banyak warisan
Ruby tidak ("sengaja" - lihat situs web Ruby, lihat di sini bagaimana hal itu dilakukan di Ruby ). Itu menggunakan kembali konsep modul sebagai jenis kelas abstrak.
Python memiliki pemahaman list / dict
Python:
res = [x*x for x in range(1, 10)]
Rubi:
res = (0..9).map { |x| x * x }
Python:
>>> (x*x for x in range(10))
<generator object <genexpr> at 0xb7c1ccd4>
>>> list(_)
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Rubi:
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'}
Rubi:
>> Hash[{1=>2, 3=>4}.map{|x,y| [x,(y*y).to_s]}]
=> {1=>"4", 3=>"16"}
Python memiliki dekorator
Hal-hal yang mirip dengan dekorator juga dapat dibuat di Ruby, dan juga dapat dikatakan bahwa hal itu tidak sepenting di Python.
Perbedaan sintaks
Ruby membutuhkan "end" atau "}" untuk menutup semua cakupannya, sementara Python hanya menggunakan spasi. Baru-baru ini ada upaya di Ruby untuk mengizinkan indentasi hanya spasi putih http://github.com/michaeledgar/seamless
Jawaban:
Ruby memiliki konsep blok , yang pada dasarnya adalah gula sintaksis di sekitar bagian kode; mereka adalah cara untuk membuat penutupan dan meneruskannya ke metode lain yang mungkin menggunakan blok tersebut atau tidak. Sebuah blok dapat dipanggil nanti melalui sebuah
yield
pernyataan.Misalnya, definisi sederhana dari sebuah
each
metode diArray
mungkin seperti ini:class Array def each for i in self yield(i) # If a block has been passed, control will be passed here. end end end
Kemudian Anda dapat memohon seperti ini:
# Add five to each element. [1, 2, 3, 4].each{ |e| puts e + 5 } > [6, 7, 8, 9]
Python memiliki fungsi / closures / lambda anonim, tetapi tidak cukup memiliki blok karena kehilangan beberapa gula sintaksis yang berguna. Namun, setidaknya ada satu cara untuk mendapatkannya secara ad-hoc. Lihat, misalnya, di sini .
sumber
Contoh Python
Fungsi adalah variabel kelas satu di Python. Anda dapat mendeklarasikan sebuah fungsi, menyebarkannya sebagai sebuah objek, dan menimpanya:
def func(): print "hello" def another_func(f): f() another_func(func) def func2(): print "goodbye" func = func2
Ini adalah fitur dasar dari bahasa skrip modern. JavaScript dan Lua melakukan ini juga. Ruby tidak memperlakukan fungsi seperti ini; menamai suatu fungsi menyebutnya.
Tentu saja, ada cara untuk melakukan hal-hal ini di Ruby, tetapi itu bukan operasi kelas satu. Misalnya, Anda bisa membungkus fungsi dengan Proc.new untuk memperlakukannya sebagai variabel - tapi itu bukan lagi fungsi; itu adalah objek dengan metode "panggilan".
Fungsi Ruby bukanlah objek kelas satu
Fungsi Ruby bukanlah objek kelas satu. Fungsi harus dibungkus dalam sebuah objek untuk menyebarkannya; objek yang dihasilkan tidak dapat diperlakukan seperti fungsi. Fungsi tidak dapat ditetapkan dengan cara kelas satu; sebagai gantinya, fungsi dalam objek kontainernya harus dipanggil untuk memodifikasinya.
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!"
sumber
x = y
bukan dengan memanggilself.class.send(:define_method, :func, method(:func2))
. "Counterexample" Anda menunjukkan bagaimana fungsi Ruby tidak kelas satu. Jika Anda tidak setuju, silakan posting jawaban Anda sendiri; jangan taruh kebingunganmu pada milikku.def ... end
dalam ruby bukanlah fungsi. Mereka adalah metode (cara Anda mendefinisikannya, dariKernel
). Metode bisa tidak terikat (menggunakan#method
metode), yang kemudian merupakan objek. Hal terdekat yang dimiliki ruby dengan fungsi adalahProc
instance, yang juga merupakan objek, dan dapat diteruskan atau dipanggil. Ini juga memiliki sintaks khusus untuk meneruskan satu callbackProc
ke suatu metode, seperti yang dibahas John Feminella dalam jawabannya .UnboundMethod
kaleng menjadi PITA, tho.Pada akhirnya semua jawaban akan menjadi subyektif pada tingkat tertentu, dan jawaban yang diposting sejauh ini cukup banyak membuktikan bahwa Anda tidak dapat menunjukkan satu fitur yang tidak dapat dilakukan dalam bahasa lain dengan cara yang sama bagusnya (jika tidak serupa). , karena kedua bahasa tersebut sangat ringkas dan ekspresif.
Saya suka sintaks Python. Namun, Anda harus menggali sedikit lebih dalam dari sintaks untuk menemukan keindahan Ruby yang sebenarnya. Ada keindahan seperti zen dalam konsistensi Ruby. Meskipun tidak ada contoh sepele yang dapat menjelaskan hal ini sepenuhnya, saya akan mencoba memberikan satu contoh di sini hanya untuk menjelaskan apa yang saya maksud.
Balik kata-kata dalam string ini:
sentence = "backwards is sentence This"
Ketika Anda memikirkan tentang bagaimana Anda akan melakukannya, Anda akan melakukan hal berikut:
Di Ruby, Anda akan melakukan ini:
sentence.split.reverse.join ' '
Persis seperti yang Anda pikirkan, dalam urutan yang sama, satu metode memanggil demi satu.
Dalam python, akan terlihat seperti ini:
" ".join(reversed(sentence.split()))
Ini tidak sulit untuk dipahami, tetapi tidak memiliki aliran yang sama. Subjek (kalimat) terkubur di tengah. Operasi adalah campuran dari fungsi dan metode objek. Ini adalah contoh yang sepele, tetapi orang menemukan banyak contoh berbeda ketika benar-benar bekerja dengan dan memahami Ruby, terutama pada tugas-tugas yang tidak sepele.
sumber
Python memiliki mentalitas "kita semua dewasa di sini". Dengan demikian, Anda akan menemukan bahwa Ruby memiliki hal-hal seperti konstanta sedangkan Python tidak (meskipun konstanta Ruby hanya memunculkan peringatan). Cara berpikir Python adalah jika Anda ingin membuat sesuatu yang konstan, Anda harus meletakkan nama variabel dalam huruf besar semua dan tidak mengubahnya.
Misalnya, Ruby:
>> PI = 3.14 => 3.14 >> PI += 1 (irb):2: warning: already initialized constant PI => 4.14
Python:
>>> PI = 3.14 >>> PI += 1 >>> PI 4.1400000000000006
sumber
Anda hanya dapat mengimpor fungsi tertentu dari modul dengan Python. Di Ruby, Anda mengimpor seluruh daftar metode. Anda bisa "membatalkan impor" mereka di Ruby, tapi itu bukan tentang semua itu.
EDIT:
mari kita ambil modul Ruby ini:
module Whatever def method1 end def method2 end end
jika Anda memasukkannya ke dalam kode Anda:
include Whatever
Anda akan melihat bahwa metode1 dan metode2 telah ditambahkan ke ruang nama Anda. Anda tidak dapat mengimpor hanya metode1 . Anda bisa mengimpor keduanya atau tidak mengimpornya sama sekali. Dengan Python, Anda hanya dapat mengimpor metode yang Anda pilih. Jika ini memiliki nama, mungkin itu akan disebut impor selektif?
sumber
import bla; bla.foo()
di Ruby?module
sebenarnya sedikit keliru. Modul pada dasarnya kelas sansnew
,allocate
metode. Mereka bekerja paling baik sebagai cara untuk berbagi kode berdasarkan kelas / objek, bukan sebagai mekanisme untuk mempartisi perpustakaan, atau untuk berbagi kode di seluruh program.Dari situs Ruby :
Kemiripan Seperti Python, di Ruby, ...
Perbedaan Tidak seperti Python, di Ruby, ...
sumber
Apa yang dimiliki Ruby atas Python adalah kemampuan bahasa skripnya. Bahasa skrip dalam konteks ini berarti digunakan untuk "kode perekat" dalam skrip shell dan manipulasi teks umum.
Ini sebagian besar dibagikan dengan Perl. Ekspresi reguler bawaan kelas satu, $ -Variabel, opsi baris perintah yang berguna seperti Perl (-a, -e) dll.
Bersama dengan sintaks yang singkat namun cepat, ini sempurna untuk jenis tugas ini.
Bagi saya Python lebih merupakan bahasa bisnis yang diketik secara dinamis yang sangat mudah dipelajari dan memiliki sintaks yang rapi. Tidak sekeren Ruby tapi rapi. Apa yang Python miliki atas Ruby bagi saya adalah banyaknya binding untuk libs lain. Pengikatan ke Qt dan pustaka GUI lainnya, banyak pustaka dukungan permainan dan dan dan. Ruby memiliki lebih sedikit. Sementara banyak binding yang digunakan misalnya untuk Database memiliki kualitas yang baik, saya menemukan libs niche lebih baik didukung dengan Python meskipun untuk perpustakaan yang sama ada juga pengikatan Ruby.
Jadi, saya akan mengatakan kedua bahasa memiliki kegunaannya dan itu adalah tugas yang menentukan mana yang akan digunakan. Keduanya cukup mudah dipelajari. Saya menggunakannya secara berdampingan. Ruby untuk scripting dan Python untuk aplikasi yang berdiri sendiri.
sumber
Saya tidak berpikir "Ruby memiliki X dan Python tidak, sedangkan Python memiliki Y dan Ruby tidak" adalah cara yang paling berguna untuk melihatnya. Mereka adalah bahasa yang sangat mirip, dengan banyak kemampuan yang sama.
Untuk sebagian besar, perbedaannya adalah apa yang dibuat bahasa itu elegan dan mudah dibaca. Untuk menggunakan contoh yang Anda kemukakan, keduanya secara teoritis memiliki lambda, tetapi programmer Python cenderung menghindarinya, dan konstruksi yang dibuat menggunakan keduanya tidak terlihat seperti dapat dibaca atau idiomatis seperti di Ruby. Jadi dengan Python, seorang programmer yang baik akan ingin mengambil rute yang berbeda untuk memecahkan masalah daripada dia akan di Ruby, hanya karena sebenarnya adalah cara yang lebih baik untuk melakukannya.
sumber
for format in respond_to()
. Therespond_to
Metode tidak kembali sesuatu yang berarti - itu hanya merespon permintaan HTTP saat ini. Bagiando
dalamrespond_to do
adalah awal dari sebuah blok. Di blok itu, kita berbicara dengan objek sementara (diberi labelformat
dalam contoh ini) yang mengimplementasikan DSL yang sangat dasar untuk merespons permintaan HTTP.Saya ingin menyarankan varian dari pertanyaan awal, "Apa yang dimiliki Ruby yang tidak dimiliki Python, dan sebaliknya?" yang mengakui jawaban yang mengecewakan, "Nah, apa yang dapat Anda lakukan dengan Ruby atau Python yang tidak dapat dilakukan di Intercal?" Tidak ada di level itu, karena Python dan Ruby adalah bagian dari keluarga kerajaan besar yang duduk di atas takhta yang hampir menyerupai Turing.
Tapi bagaimana dengan ini:
Apa yang bisa dilakukan dengan anggun dan baik dengan Python yang tidak bisa dilakukan di Ruby dengan keindahan dan teknik yang bagus, atau sebaliknya?
Itu mungkin jauh lebih menarik daripada sekadar perbandingan fitur.
sumber
Python memiliki sintaksis bawaan yang eksplisit untuk pemahaman daftar dan generator sedangkan di Ruby Anda akan menggunakan blok peta dan kode.
Membandingkan
list = [ x*x for x in range(1, 10) ]
untuk
res = (1..10).map{ |x| x*x }
sumber
res=map(2 .__rpow__, range(1,10))
"Variabel yang dimulai dengan huruf kapital menjadi konstanta dan tidak dapat dimodifikasi"
Salah. Mereka bisa.
Anda hanya mendapat peringatan jika melakukannya.
sumber
Sedikit lebih banyak di sisi infrastruktur:
Python memiliki integrasi yang jauh lebih baik dengan C ++ (melalui hal-hal seperti Boost.Python , SIP , dan Py ++ ) daripada Ruby, di mana opsinya tampaknya menulis langsung pada API interpreter Ruby (yang juga dapat Anda lakukan dengan Python, tentu saja, tetapi dalam kedua kasus melakukannya adalah tingkat rendah, membosankan, dan rawan kesalahan) atau gunakan SWIG (yang, meskipun berfungsi dan pasti bagus jika Anda ingin mendukung banyak bahasa, tidak sebagus Boost. Python atau SIP jika Anda secara khusus ingin mengikat C ++).
Python memiliki sejumlah lingkungan aplikasi web (Django, Pylons / Turbogears, web.py, mungkin setidaknya setengah lusin lainnya), sedangkan Ruby (efektif) memiliki satu: Rails. (Kerangka web Ruby lain memang ada, tetapi tampaknya kesulitan mendapatkan banyak daya tarik terhadap Rails). Apakah aspek ini baik atau buruk? Sulit untuk dikatakan, dan mungkin sangat subjektif; Saya dapat dengan mudah membayangkan argumen bahwa situasi Python lebih baik dan situasi Ruby lebih baik.
Secara budaya, komunitas Python dan Ruby tampak agak berbeda, tetapi saya hanya dapat mengisyaratkan hal ini karena saya tidak memiliki banyak pengalaman dalam berinteraksi dengan komunitas Ruby. Saya menambahkan ini sebagian besar dengan harapan bahwa seseorang yang memiliki banyak pengalaman dengan keduanya dapat memperkuat (atau menolak) pernyataan ini.
sumber
Salin / tempel tanpa malu-malu dari: Alex Martelli menjawab tentang utas " Apa yang lebih baik tentang Ruby daripada Python " dari milis comp.lang.python .
sumber
Beberapa lainnya dari:
http://www.ruby-lang.org/en/documentation/ruby-from-other-languages/to-ruby-from-python/
(Jika saya telah salah mengartikan sesuatu atau salah satu dari ini telah berubah di sisi Ruby sejak halaman itu diperbarui, seseorang silakan mengedit ...)
String bisa berubah di Ruby, bukan di Python (di mana string baru dibuat oleh "perubahan").
Ruby memiliki beberapa konvensi kasus yang diberlakukan, sedangkan Python tidak.
Python memiliki daftar dan tupel (daftar yang tidak dapat diubah). Ruby memiliki array yang sesuai dengan daftar Python, tetapi tidak ada varian yang tidak dapat diubah.
Dengan Python, Anda bisa langsung mengakses atribut objek. Di Ruby, selalu melalui metode.
Di Ruby, tanda kurung untuk panggilan metode biasanya opsional, tetapi tidak di Python.
Ruby memiliki public, private, dan protected untuk memaksakan akses, bukan konvensi Python menggunakan garis bawah dan name mangling.
Python memiliki banyak warisan. Ruby memiliki "mixin."
Dan tautan lain yang sangat relevan:
http://c2.com/cgi/wiki?PythonVsRuby
Yang, khususnya, tautan ke yang bagus lainnya oleh Alex Martelli , yang juga memposting banyak hal hebat di sini di SO:
http://groups.google.com/group/comp.lang.python/msg/028422d707512283
sumber
Saya tidak yakin tentang ini, jadi saya menambahkannya sebagai jawaban terlebih dahulu.
Python memperlakukan metode tidak terikat sebagai fungsi
Itu berarti Anda dapat memanggil metode seperti
theobject.themethod()
atau denganTheClass.themethod(anobject)
.Sunting: Meskipun perbedaan antara metode dan fungsi kecil di Python, dan tidak ada di Python 3, itu juga tidak ada di Ruby, hanya karena Ruby tidak memiliki fungsi. Saat Anda mendefinisikan fungsi, Anda sebenarnya mendefinisikan metode pada Objek.
Tetapi Anda masih tidak dapat menggunakan metode satu kelas dan memanggilnya sebagai fungsi, Anda harus mengikatnya kembali ke objek yang ingin Anda panggil, yang jauh lebih banyak rintangan.
sumber
TheClass.instance_method(:themethod).bind(anobject).call
akan menjadi ruby yang setara.Object
.Saya ingin menyebutkan API deskriptor Python yang memungkinkan seseorang menyesuaikan "komunikasi" objek-ke-atribut. Perlu juga dicatat bahwa, dengan Python, seseorang bebas mengimplementasikan protokol alternatif melalui menimpa default yang diberikan melalui implementasi default
__getattribute__
metode tersebut. Izinkan saya memberikan lebih banyak detail tentang hal tersebut di atas. Deskriptor adalah kelas reguler dengan__get__
,__set__
dan / atau__delete__
metode. Ketika juru bahasa menemukan sesuatu sepertianObj.anAttr
, berikut ini dilakukan:__getattribute__
metodeanObj
dipanggil__getattribute__
mengambil objek anAttr dari kelas dict__get__
,__set__
atau__delete__
objek yang dapat dipanggilSeperti yang telah disebutkan, ini adalah perilaku default. Satu bebas untuk mengubah protokol dengan mengimplementasikan ulang
__getattribute__
.Teknik ini jauh lebih kuat daripada dekorator.
sumber
Ruby memiliki dukungan kelanjutan bawaan menggunakan
callcc
.Karenanya Anda dapat menerapkan hal-hal keren seperti amb-operator
sumber
Pada tahap ini, Python masih memiliki dukungan unicode yang lebih baik
sumber
Python memiliki docstrings dan ruby tidak ... Atau jika tidak, mereka tidak dapat diakses semudah di python.
Ps. Jika saya salah, tolong, tinggalkan contoh? Saya memiliki solusi yang saya bisa monkeypatch ke dalam kelas dengan cukup mudah tetapi saya ingin memiliki semacam fitur docstring dalam "cara asli".
sumber
Ruby memiliki perulangan baris demi baris di atas file input (tanda '-n') dari baris perintah sehingga dapat digunakan seperti AWK. Ruby one-liner ini:
ruby -ne 'END {puts $.}'
akan menghitung baris seperti satu baris AWK:
awk 'END{print NR}'
Ruby mendapatkan fitur ini melalui Perl, yang mengambilnya dari AWK sebagai cara agar sysadmin bergabung dengan Perl tanpa harus mengubah cara mereka melakukan sesuatu.
sumber
python -c "import sys; print len(list(sys.stdin))"
Ruby memiliki sigil dan ranting, Python tidak.
Sunting : Dan satu hal yang sangat penting yang saya lupa (setelah semua, yang sebelumnya hanya nyala sedikit :-p):
Python memiliki kompiler JIT ( Psyco ), bahasa tingkat yang lebih rendah untuk menulis kode yang lebih cepat ( Pyrex ) dan kemampuan untuk menambahkan kode C ++ inline ( Weave ).
sumber
Python saya berkarat, jadi beberapa di antaranya mungkin ada di python dan saya tidak ingat / tidak pernah belajar di tempat pertama, tetapi berikut adalah beberapa yang pertama saya pikirkan:
Spasi Putih
Ruby menangani whitespace yang sangat berbeda. Sebagai permulaan, Anda tidak perlu membuat indentasi apa pun (yang berarti tidak masalah jika Anda menggunakan 4 spasi atau 1 tab). Itu juga melakukan kelanjutan smart line, jadi yang berikut ini valid:
def foo(bar, cow)
Pada dasarnya, jika Anda mengakhiri dengan operator, itu akan mencari tahu apa yang sedang terjadi.
Mixins
Ruby memiliki mixin yang dapat memperluas instance, bukan kelas penuh:
module Humor def tickle "hee, hee!" end end a = "Grouchy" a.extend Humor a.tickle » "hee, hee!"
Enum
Saya tidak yakin apakah ini sama dengan generator, tetapi pada Ruby 1.9 ruby sebagai enum, jadi
>> enum = (1..4).to_enum => #<Enumerator:0x1344a8>
Referensi: http://blog.nuclearsquid.com/writings/ruby-1-9-what-s-new-what-s-changed
"Argumen Kata Kunci"
Kedua item yang terdaftar di sana didukung di Ruby, meskipun Anda tidak dapat melewatkan nilai default seperti itu. Anda bisa pergi secara berurutan
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
Perhatikan bahwa c = 5 sebenarnya memberikan variabel c dalam lingkup panggilan nilai 5, dan menetapkan parameter b nilai 5.
atau Anda dapat melakukannya dengan hash, yang membahas masalah kedua
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
Referensi: Panduan Progammer Pragmatis untuk Ruby
sumber
(
,[
atau{
Anda dapat memiliki kode dalam definisi kelas di Ruby dan Python. Namun, di Ruby Anda memiliki referensi ke kelas (mandiri). Dengan Python Anda tidak memiliki referensi ke kelas tersebut, karena kelas tersebut belum ditentukan.
Sebuah contoh:
class Kaka puts self end
self dalam hal ini adalah kelas, dan kode ini akan mencetak "Kaka". Tidak ada cara untuk mencetak nama kelas atau dengan cara lain mengakses kelas dari badan definisi kelas dengan Python.
sumber
class
pernyataan.Sintaks bukanlah hal yang kecil, ia berdampak langsung pada cara kita berpikir. Ini juga memiliki efek langsung pada aturan yang kami buat untuk sistem yang kami gunakan. Sebagai contoh, kita memiliki urutan operasi karena cara kita menulis persamaan atau kalimat matematika. Notasi standar untuk matematika memungkinkan orang membacanya lebih dari satu cara dan sampai pada jawaban yang berbeda dengan persamaan yang sama. Jika kita menggunakan awalan atau notasi postfix kita akan membuat aturan untuk membedakan angka yang akan dimanipulasi daripada hanya memiliki aturan untuk urutan menghitung nilai.
Notasi standar memperjelas angka apa yang kita bicarakan sambil membuat urutan penghitungannya menjadi ambigu. Prefix dan notasi postfix membuat urutan penghitungan menjadi polos sambil membuat angka menjadi ambigu. Python sudah memiliki lambda multiline jika bukan karena kesulitan yang disebabkan oleh spasi putih sintaksis. (Ada proposal untuk menarik hal semacam ini tanpa perlu menambahkan pembatas blok secara eksplisit.)
Saya merasa lebih mudah untuk menulis kondisi di mana saya ingin sesuatu terjadi jika kondisi salah jauh lebih mudah untuk menulis dengan pernyataan kecuali di Ruby daripada konstruksi "jika-tidak" yang setara secara semantik di Ruby atau bahasa lain misalnya. Jika sebagian besar bahasa yang digunakan orang saat ini memiliki kekuatan yang sama, bagaimana sintaks setiap bahasa dapat dianggap sebagai hal yang sepele? Setelah fitur khusus seperti blok dan mekanisme pewarisan, dll. Sintaks adalah bagian terpenting dari sebuah bahasa, hampir tidak merupakan hal yang dangkal.
Apa yang dangkal adalah kualitas estetika keindahan yang kita anggap berasal dari sintaksis. Estetika tidak ada hubungannya dengan cara kerja kognisi kita, sintaks.
sumber
Terkejut melihat tidak ada yang disebutkan tentang mekanisme "metode hilang" ruby. Saya akan memberikan contoh metode find_by _... di Rails, sebagai contoh kekuatan fitur bahasa tersebut. Dugaan saya adalah bahwa sesuatu yang serupa dapat diterapkan dengan Python, tetapi sepengetahuan saya itu tidak ada secara asli.
sumber
method_missing
dapat ditiru di Python dalam beberapa kasus:class M(): def __getattr__(self, n): return lambda: "Missing! " + n; M().hi()
. Namun, ada sedikit perbedaan dan saya ragu itu idiomatis dengan Python :-)Perbedaan lain dalam lambda antara Python dan Ruby ditunjukkan oleh masalah Generator Akumulator Paul Graham . Dicetak ulang di sini:
Di Ruby, Anda dapat melakukan ini:
def foo(n) lambda {|i| n += i } end
Dengan Python, Anda akan membuat objek untuk menampung keadaan n:
class foo(object): def __init__(self, n): self.n = n def __call__(self, i): self.n += i return self.n
Beberapa orang mungkin lebih suka pendekatan Python eksplisit karena lebih jelas secara konseptual, bahkan jika itu sedikit lebih bertele-tele. Anda menyimpan keadaan seperti yang Anda lakukan untuk hal lain. Anda hanya perlu memikirkan gagasan tentang objek yang dapat dipanggil. Tetapi terlepas dari pendekatan mana yang lebih disukai secara estetika, itu menunjukkan satu hal di mana Ruby lambda adalah konstruksi yang lebih kuat daripada Python.
sumber
def foo(n): def f(i): return n + i return f
.def foo(n): L=[n] def f(i): L[0] += i return L[0] return f
. Di Python3 Anda bisa menggunakannonlocal
kata kunci.python memberi nama argumen opsional
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 hanya memposisikan argumen karena b = 2 dalam deklarasi fungsi merupakan pengaruh yang selalu ditambahkan.
sumber
def my_method(param1, optional = false)
bekerja di Ruby 1.8.6, 1.8.7, dan mungkin 1.9!b
parameter dalamfunc
panggilan dan masih mempertahankan defaultnya. Artinya,b
adalah argumen kedua dalam tanda tangan, tetapi dia bisa melewatinya dengan mengawali parameter kedua denganc=
. Ruby menggunakan hash untuk mensimulasikan ini, tetapi tidak persis sama.Ruby memiliki dokumentasi tertanam:
=begin You could use rdoc to generate man pages from this documentation =end
sumber
http://c2.com/cgi/wiki?PythonVsRuby
http://c2.com/cgi/wiki?SwitchedFromPythonToRuby
http://c2.com/cgi/wiki?SwitchedFromRubyToPython
http://c2.com/cgi/wiki ? UsingPythonDontNeedRuby
http://c2.com/cgi/wiki?UsingRubyDontNeedPython
sumber
Dengan Cargo Anda dapat " meminta pustaka tanpa mengacaukan namespace Anda ".
# foo-1.0.0.rb class Foo VERSION = "1.0.0" end # foo-2.0.0.rb class Foo VERSION = "2.0.0" end
sumber