Możliwe są niejawne konwersje. Sytuacja, w której masz kłopoty, polega na tym, że nie wiesz, w jaki sposób coś powinno działać.
Przykładem tego jest Javascript, w którym +
operator działa w różny sposób w różnym czasie.
>>> 4 + 3
7
>>> "4" + 3
43
>>> 4 + "3"
43
Jeśli jeden z argumentów jest łańcuchem, to +
operator jest łańcuchem łączenia, w przeciwnym razie jest to dodawanie.
Jeśli otrzymujesz argument i nie wiesz, czy jest to ciąg znaków, czy liczba całkowita i chcesz dodać do niego argument, może to być trochę bałaganu.
Innym sposobem radzenia sobie z tym jest z Podstawowego dziedzictwa (z którego pochodzi perl - patrz Programowanie jest trudne, chodźmy skrypty ... )
W Basicu len
funkcja ma sens tylko przywoływana na String (docs dla visual basic : „Dowolne prawidłowe wyrażenie String lub nazwa zmiennej. Jeśli Expression jest typu Object, funkcja Len zwraca rozmiar, który zostanie zapisany w pliku przez funkcja FilePut. ”).
Perl podąża za tą koncepcją kontekstu. Zamieszanie występujące w JavaScript z niejawną konwersją typów dla +
operatora będącego czasem dodawaniem, a czasem konkatenacją nie występuje w Perlu, ponieważ zawsze+
jest dodawaniem i zawsze jest konkatenacją..
Jeśli coś jest używane w kontekście skalarnym, jest to skalar (np. Używając listy jako skalara, lista zachowuje się tak, jakby była liczbą odpowiadającą jej długości). Jeśli używasz operatora łańcucha ( eq
do testu równości, cmp
do porównania łańcucha), skalar jest używany tak, jakby był łańcuchem. Podobnie, jeśli coś zostało użyte w kontekście matematycznym ( ==
do testu równości i <=>
porównania numerycznego), skalar jest używany tak, jakby był liczbą.
Podstawową zasadą wszystkich programów jest „robienie rzeczy, które najmniej zaskakują człowieka”. Nie oznacza to, że nie ma w tym niespodzianek, ale staramy się jak najmniej zaskoczyć osobę.
Idąc do bliskiego kuzyna perl - php, zdarzają się sytuacje, w których operator może działać na coś w kontekście łańcuchowym lub liczbowym, a zachowanie może być zaskakujące dla ludzi. ++
Operator jest jednym z przykładów. W przypadku liczb zachowuje się dokładnie tak, jak oczekiwano. Podczas działania na łańcuch, na przykład "aa"
, zwiększa łańcuch ( $foo = "aa"; $foo++; echo $foo;
drukuje ab
). Będzie również przewracał się, aby az
po zwiększeniu stał się ba
. Nie jest to jeszcze szczególnie zaskakujące.
$foo = "3d8";
echo "$foo\n";
$foo++;
echo "$foo\n";
$foo++;
echo "$foo\n";
$foo++;
echo "$foo\n";
( ideone )
To drukuje:
3d8
3d9
3e0
4
Witaj w niebezpieczeństwach niejawnych konwersji i działania różnych operatorów na tym samym łańcuchu. (Uchwyty Perl że kod blokują trochę inaczej - uzna, że "3d8"
gdy ++
operator jest stosowana jest wartość liczbowa od samego początku i idzie 4
od razu ( ideone ) - takie zachowanie jest dobrze opisana w perlop: Auto-inkrementacja i Auto-ubytek )
Teraz, dlaczego jeden język robi coś w jedną stronę, a inny w inny sposób, przechodzi do myśli projektowych projektantów. Filozofią Perla jest to, że można to zrobić na więcej niż jeden sposób - i mogę wymyślić kilka sposobów wykonania niektórych z tych operacji. Z drugiej strony Python ma filozofię opisaną w PEP 20 - Zen of Python, która stwierdza (między innymi): „Powinien istnieć jeden - a najlepiej tylko jeden - oczywisty sposób”.
Te różnice projektowe doprowadziły do różnych języków. Jest jeden sposób na uzyskanie długości liczby w Pythonie. Niejawna konwersja jest sprzeczna z tą filozofią.
Literatura pokrewna: Dlaczego Ruby nie ma niejawnej konwersji Fixnum na String?
perl -e 'print length(100);'
wydruki 3.