Як зазначали інші, терміни "сильно набрані" та "слабо набрані" мають стільки різних значень, що на ваше запитання немає однозначної відповіді. Однак, оскільки ви спеціально згадали Perl у своєму питанні, дозвольте мені спробувати пояснити, у якому сенсі Perl слабо набраний.
Справа в тому, що в Perl немає такого поняття, як "ціла змінна", "плаваюча змінна", "рядкова змінна" або "булева змінна". Насправді, наскільки користувач може (як правило) сказати, не існує навіть цілих, плаваючих, рядкових або булевих значень : все, що у вас є, є "скалярами", які є всіма цими речами одночасно. Так що ви можете, наприклад, написати:
$foo = "123" + "456"; # $foo = 579
$bar = substr($foo, 2, 1); # $bar = 9
$bar .= " lives"; # $bar = "9 lives"
$foo -= $bar; # $foo = 579 - 9 = 570
Звичайно, як ви правильно зазначаєте, все це можна розглядати як примус просто типу. Але справа в тому, що в Perl типи завжди примусові. Насправді, користувачеві досить важко сказати, яким може бути внутрішній "тип" змінної: у рядку 2 у моєму прикладі вище, запитуючи, чи є значення $bar
рядка "9"
чи числа, 9
є майже безглуздим, оскільки, як що стосується Перла, то це те саме . Дійсно, навіть скаляр Perl може внутрішньо мати одночасно і рядок, і числове значення, як, наприклад,$foo
другого рядка вище.
Зворотний бік усього цього полягає в тому, що, оскільки змінні Perl не типовані (або, вірніше, не піддають користувачеві свій внутрішній тип), оператори не можуть бути перевантажені робити різні дії для різних типів аргументів; ви не можете просто сказати "цей оператор зробить X для чисел і Y для рядків", тому що оператор не може (не буде) сказати, які саме значення є його аргументами.
Так, наприклад, Perl має і потребує як оператора додавання чисел ( +
), так і оператора конкатенації рядків ( .
): як ви бачили вище, цілком чудово додати рядки ( "1" + "2" == "3"
) або об'єднати числа ( 1 . 2 == 12
). Аналогічно, числові оператори порівняння ==
, !=
, <
, >
, <=
, >=
і <=>
порівнювати числові значення своїх аргументів, а оператори порівняння рядків eq
, ne
, lt
, gt
, le
, ge
і cmp
порівняти їх лексикографічно як рядки. Так 2 < 10
, але 2 gt 10
(але "02" lt 10
, поки "02" == 2
). (Зверніть увагу, деякі інші мови, як-от JavaScript, намагаються вмістити слабкий текст, схожий на Perlтакож роблять перевантаження оператора. Це часто призводить до потворності, як втрата асоціативності +
.)
(Муха в мазі тут полягає в тому, що з історичних причин у Perl 5 є кілька кутових випадків, як битові логічні оператори, поведінка яких залежить від внутрішнього представлення їх аргументів. Це, як правило, вважається дратівливою вадою дизайну, оскільки внутрішнє представництво може змінитися з дивних причин, і тому передбачення того, що роблять ці оператори в даній ситуації, може бути складним.)
Все , що сказав, можна стверджувати , що Perl дійсно є сильні типи; вони просто не такі види, яких ви могли б очікувати. Зокрема, крім «скалярного» типу, обговореного вище, Perl також має два структуровані типи: «масив» та «хеш». Вони дуже відрізняються від скалярів до точки, коли змінні Perl мають різні знаки, що вказують на їх тип ( $
для скалярів, @
для масивів, %
для хешів) 1 . Там є правила примусу між цими типами, так що ви можете написати , наприклад %foo = @bar
, але багато хто з них є вельми втратами, наприклад, $foo = @bar
привласнює довжину масиву @bar
в$foo
, а не його зміст. (Крім того, є кілька інших дивних типів, наприклад, шрифти та ручки вводу / виводу, які ви не часто бачите.)
Також невеликий хит у цьому приємному дизайні - це існування еталонних типів, які є особливим видом скалярів (і які можна відрізнити від звичайних скалярів, використовуючи ref
оператор). Можна використовувати посилання як звичайні скаляри, але їхні рядкові / числові значення не особливо корисні, і вони, як правило, втрачають свою особливу орієнтирність, якщо ви модифікуєте їх за допомогою звичайних скалярних операцій. Також будь-яка змінна Perl 2 може бутиbless
редагувати до класу, перетворюючи її на об'єкт цього класу; система класу ОО в Перлі дещо ортогональна описаній вище системі примітивного типу (або безхарактерності), хоча вона також "слабка" в сенсі слідування вводу качкипарадигма. Загальна думка полягає в тому, що якщо ви виявите, що ви перевіряєте клас об’єкта в Perl, ви щось робите не так.
1 Власне, sigil позначає тип значення, до якого звертаються, так що, наприклад, @foo
позначається перший скаляр у масиві $foo[0]
. Дивіться perlfaq4 для більш детальної інформації.
2 До об'єктів у Perl (як правило) можна отримати доступ через посилання на них, але насправді виходить bless
змінна (можливо, анонімна) змінна, на яку посилаються опорні точки. Однак благословення дійсно є властивістю змінної, а не її значення, так що, наприклад, присвоєння фактичної блаженної змінної іншій просто дає вам дрібну копію її. Дивіться perlobj для більш детальної інформації.