Porównaj ceny domen i usług IT, sprzedawców z całego świata

Czy „małpa łata” naprawdę jest taka zła?


Niektóre języki, takie jak Ruby i JavaScript mają otwarte klasy, które pozwalają na zmianę interfejsów nawet podstawowych klas, takich jak liczby, linie, tablice itp. Oczywiście, może pomylić innych, którzy znają interfejsy API, ale są Jest ważnym powodem, aby uniknąć jej inaczej, zakładając, że dodasz do interfejsu i nie zmieniaj istniejącego zachowania?
Na przykład byłoby miło dodać tablicę Lub twoje tablice rubinowe mogą korzystać z wygodnej metody "sum", która używa "wstrzykiwań". Podczas gdy zmiany są wyizolowane z systemów (na przykład nie jesteś częścią pakietu oprogramowania, który wydasz do dystrybucji), czy istnieje dobry powód, aby nie używać tej funkcji językowej?
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Monkey Fix, podobnie jak wiele narzędzi z zestawu narzędzi programistycznych, może być używany dobrze lub źle. Pytanie brzmi, gdzie ostatecznie takie narzędzia są najczęściej używane. Z mojego doświadczenia z Rubim wynika, że ​​waga jest po „złej” stronie.
Więc jakie jest „złe” zastosowanie małpiego łatania? Cóż, małpa łatanie generalnie pozostawia szeroko otwarte na duże, potencjalnie niewykrywalne kolizje. Mam klasę
A
. Mam pewien rodzaj małpiego modułu naprawy
MB
, który naprawia
A
, uwzględniając
method1
,
method2
i
method3
. Mam inny moduł naprawy małp
MC
, który również naprawia
A
, uwzględniając
method2
,
method3
i
method4 . Teraz jestem zagubiony. Wzywam[code]instance_of_A.method2
: czyja metoda jest wywoływana? Odpowiedź na to pytanie może zależeć od wielu czynników: [/code]
  • W jakiej kolejności wprowadziłem moduły poprawek
  • Czy plastry są nakładane natychmiast, czy pod pewnymi warunkami
  • AAAAAAARGH! Pająki są poza moimi oczami wewnątrz!

OK, więc numer 3 jest prawdopodobnie zbyt melodramatyczny ....
W każdym razie jest to problem z łataniem małpy: straszne problemy z konfliktem. Biorąc pod uwagę bardzo dynamiczną naturę języków, które zazwyczaj ją obsługują, napotkasz już wiele potencjalnych problemów z „upiornymi działaniami na odległość”; małpa poprawka tylko je dodaje.
Posiadanie dostępnych łatek małp jest dobre, jeśli jesteś odpowiedzialnym programistą. Niestety, IME zdarza się, że ktoś widzi łatkę z małpą i mówi: „Kochanie! Po prostu to naprawię, zamiast sprawdzać, czy inne mechanizmy mogą być bardziej odpowiednie”. Jest to sytuacja z grubsza analogiczna do baz kodu Lispa tworzonych przez ludzi, którzy skłaniają się ku makrom, zanim pomyślą o zrobieniu tego jako funkcji.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Wikipedia zawiera podsumowanie pułapek poprawki małpy:
http://en.wikipedia.org/wiki/ Monkey_patch # pod wodą
http://en.wikipedia.org/wiki/Monkey_patch#Pitfalls
Kamienie
Na wszystko jest czas i miejsce, a także na łatanie małp. Doświadczeni programiści mają w zanadrzu wiele sztuczek i wiedzą, kiedy ich używać. Rzadko jest to technika sama w sobie, która jest „zła”, wystarczy jej nieostrożne użycie.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Chociaż zmiany są izolowane od
Twoich systemów (na przykład nie są częścią
pakiet oprogramowania, dla którego wydajesz
rozprzestrzenianie się), czy istnieje dobry powód
nie używaj tego języka
funkcjonować?

Jako samotny programista pracujący nad pojedynczym problemem nie ma problemu z rozszerzaniem lub modyfikowaniem obiektów natywnych. Ponadto w przypadku większych projektów należy dokonać wyboru zespołowego.
Osobiście nie podoba mi się, gdy zmieniają się obiekty natywne w javascript, ale jest to powszechna praktyka i właściwy wybór. Jeśli masz zamiar napisać bibliotekę lub kod, który jest przeznaczony do użytku przez innych, zdecydowanie bym tego unikał.
Jednak jest to właściwy wybór projektu, aby umożliwić użytkownikowi ustawienie flagi konfiguracji, która mówi, że należy nadpisać własne obiekty wygodnymi metodami, ponieważ jest to tak wygodne.
Aby zilustrować określoną pułapkę JavaScript.
Array.protoype.map = function map() { ... };var a = [2];
for (var k in a) {
console.log(a[k]);
}
// 2, function map() { ... }

Tego problemu można uniknąć, używając ES5, który umożliwia wstrzykiwanie niewliczalnych właściwości do obiektu.
Jest to zasadniczo wybór konstrukcji wysokiego szczebla, a każdy powinien znać/zgadzać się z tym.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Całkowicie rozsądne jest użycie „małpich poprawek” w celu naprawienia określonego, znanego problemu, gdzie alternatywą byłoby oczekiwanie na łatkę, która go naprawi. Oznacza to tymczasowe przyjęcie odpowiedzialności za naprawianie czegoś, dopóki „właściwa” poprawka nie zostanie oficjalnie wydana, którą możesz wdrożyć.
Wyważona opinia Gilada Brachi na temat łatania małp:

http://gbracha.blogspot.com/20 ... .html
http://gbracha.blogspot.com/20 ... .html
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Warunki, które opisujesz - dodawanie (nie modyfikowanie) istniejącego zachowania i nieudostępnianie kodu do świata zewnętrznego - wydają się względnie bezpieczne. Jednak mogą pojawić się problemy, jeśli następna wersja Ruby, JavaScript lub Rails zmieni swoje API. Na przykład, co się stanie, jeśli jakaś przyszła wersja jQuery sprawdzi, czy Array.map jest już zdefiniowana i zakłada, że ​​jest to wersja mapy EMCA5Script, podczas gdy w rzeczywistości jest to Twoja małpa poprawka?
Podobnie, co jeśli definiujesz "sumę" w Rubim i pewnego dnia zdecydujesz, że chcesz użyć tego kodu ruby ​​w Railsach lub dodać obsługę aktywnych klejnotów do swojego projektu? Aktywne wsparcie definiuje również metodę sum (na Enumerable), więc występuje kolizja.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Jeśli chodzi o JavaScript:

Czy istnieje dobry powód, aby tego uniknąć, zakładając, że dodajesz do interfejsu i nie zmieniasz istniejącego zachowania?

Tak. Najgorszy przypadek, nawet jeśli się nie zmieniasz

istnięjące

zachowanie, możesz zranić

przyszłość

Składnia języka.
Dokładnie to się stało z
Array.prototype.flatten
https://github.com/tc39/proposal-flatMap/pull/56
i
Array.prototype.contains
https://bugzilla.mozilla.org/s ... 59... Krótko mówiąc, specyfikacja została napisana dla tych metod, do których dotarły ich sugestie

etap 3
https://tc39.github.io/process-document/
A następnie przeglądarze zaczęli go wysyłać. Ale w obu przypadkach stwierdzono, że istnieją starożytne biblioteki, które naprawiają wbudowaną tablicę
z własnymi metodami. 

o tej samej nazwie co nowe metody

i zachowywał się inaczej; w rezultacie strony pękały, przeglądarki musiały zrezygnować z implementacji nowych metod, a specyfikacja musiała zostać zweryfikowana. (Nazwy metod zostały zmienione.)
Jeśli zmienisz obiekt wbudowany, taki jak
Array

we własnej przeglądarce, na swoim komputerze
, to normalne. (Jest to bardzo przydatna technika tworzenia niestandardowych skryptów). Jeśli zmodyfikujesz obiekt wbudowany w swojej witrynie publicznej, jest to mniej normalne - tak jest

mogą

ostatecznie prowadzą do problemów, takich jak te opisane powyżej. Jeśli masz szczęście, że sobie poradzisz

świetna strona

(np. stackoverflow.com) i zmutujesz obiekt wbudowany, możesz prawie zagwarantować, że przeglądarki odmówią wdrożenia nowych funkcji/technik, które zepsują Twoją witrynę (ponieważ wtedy użytkownicy tej przeglądarki nie będą mogli korzystać z Twojej witryny bardziej prawdopodobne, że przejdą do innej przeglądarki). (cm.

tutaj
https://coderoad.ru/55934490/
wyjaśnienie tego rodzaju interakcji między twórcami specyfikacji a producentami przeglądarek)
Wszystko, co zostało powiedziane, dotyczy

konkretny przykład

w twoim pytaniu:

Na przykład byłoby miło dodać implementację Array.map do przeglądarek internetowych, które nie implementują 5.edycji ECMAScript

Jest to bardzo popularna i godna zaufania technika zwana

Wypełnienie
https://en.wikipedia.org/wiki/Polyfill_(programming)
.

Wypełnienie to kod implementujący funkcję w przeglądarkach internetowych, które jej nie obsługują. Najczęściej odnosi się do biblioteki JavaScript, która implementuje standard sieciowy HTML5, albo ustalony standard (obsługiwany przez niektóre przeglądarki) w starszych przeglądarkach, albo proponowany standard (nieobsługiwany przez żadne przeglądarki) w istniejących przeglądarkach

Na przykład, jeśli napisałeś polyfill dla
Array.prototype.map
(lub, w nowszym przykładzie, dla
Array.prototype.flatMap
), który

w pełni spełnione
Oficjalna specyfikacja etapu 4
https://tc39.github.io/ecma262 ... e.map
a następnie uruchomił kod definiujący
Array.prototype.flatMap
w przeglądarkach, które jeszcze go nie miały:
if (!Array.prototype.flatMap) {
Array.prototype.flatMap = function(...
// ...
}
}

Jeśli implementacja jest poprawna, jest to całkowicie w porządku i jest wykonywane bardzo często w całym Internecie, aby starsze przeglądarki mogły zrozumieć nowe metody.

polyfill.io
http://www.polyfill.io/
to powszechna usługa w tego rodzaju sprawach.

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się