Myślałem, że jednym z podstawowych elementów OOP jest to, że mamy przedmioty, którymi jesteśmy zainteresowani, a następnie wysyłamy do nich wiadomości.
Może więc wydawać się naturalne, że mam kolekcję przedmiotów i muszę je ułożyć w jeden sznurek, aby to zrobić:
["x", "o", "o"].join(" | ") # joining a tic-tac-toe row in Ruby
(Smalltalk robi to w ten sam sposób). " | "
Jest w jakiś sposób traktowane jako argument, jeden znak, jak się do niej przyłączyć. Może być " "
też, jeśli plansza ma być prostsza. Zatem element łączący " | "
nie jest czymś, co szczególnie nas interesuje - nie są to główne obiekty w programie, które mają szczególne znaczenie lub znaczenie.
Jeśli Python robi to za pomocą
" | ".join(["x", "o", "o"])
To trochę dziwne, że prawie czujemy, że przekazujemy argument do argumentu, aby o tym powiedzieć. Może Python jest bardziej proceduralny? Powiedzieć łączącemu łańcuchowi, aby wykonał dla nas jakiś obowiązek?
Czy ma to zapisać implementację, abyśmy nie musieli definiować join
dla każdej klasy kolekcji, którą mamy? Ale czy nie jest prawdą, że możemy napisać tylko raz dla dowolnej klasy kolekcji, na przykład w Ruby:
module Enumerable
def my_join(joiner)
self.inject {|a,b| a.to_s + joiner + b.to_s}
end
end
(coś w tym stylu, wzywając to_s
każdy element, polegając na to_s
każdej klasie, aby wykonać swoją własną rzecz, przekonwertować na ciąg, a następnie połączyć je). Zatem nie musimy implementować dla każdej String, Hash, Set, ani żadnej innej klasy kolekcji, którą mamy.
A może Python się nie zgadza? Używa len("abc")
i wydaje się, że type([])
zamiast Python3, "abc".len()
a [].type()
nawet. Czy Python robi to w ten sposób z powodów projektowych?
Maybe Python is more procedural?
Python był językiem proceduralnym z kilkoma dodatkami funkcjonalnymi („Python nabył lambda, redukcję (), filter () i map (), dzięki uprzejmości hakera Lisp, który za nimi tęsknił i przesłał łaty robocze”), dopóki coś nie wydaje się być gdzieś w wersji 2. To było około półtorej dekady po pierwszej pracy.