Ключевое слово Call - устарело или нет - PullRequest
8 голосов
/ 08 июня 2019

enter image description here

Я видел, как со временем люди упоминали, что Заявление о вызове устарело, но я не могу найти ничего официального, чтобы поддержать это утверждение.

На странице документации произошло довольно недавнее обновление страницы ( 12/03/2018 ), поэтому я не могу сказать, что это устаревшая информация.

Я использовал Call в своем коде, чаще всего просто потому, что нахожу это:

Call function(arg1, arg2, arg3) быть более читабельным, чем function arg1, arg2, arg3

Теперь по вопросу , кто-нибудь может дать некоторое представление о том, почему я больше не должен использовать выражение Call? Если вы говорите, что устарела, просьба предоставить ссылка на ресурс.

Если этот вопрос противоречит правилам сайта, пожалуйста, дайте мне знать, я с удовольствием удалю его сам, хотя было бы неплохо получить ответ.

Ответы [ 3 ]

15 голосов
/ 03 июля 2019

Согласованность - король

Если вы звоните Sub или Function, то не имеет значения.Важно то, что согласованность , а - это , что Call -любители утверждают, используя ключевое слово.Согласованность с тем, требуются ли круглые скобки вокруг списка аргументов.

Поэтому вместо этого простого неявного оператора вызова:

MsgBox "I'm a function but you're discarding my return value, so no parentheses."

Мы получаем такие вещи:

MsgBox ("I'm a function but you're discarding my return value, and this call looks weird.")

И мне еще предстоит увидеть, что Call на самом деле используется с любым видом фактической консистенции :

Call MsgBox("I'm a function but you're discarding my return value, so I have a Call keyword.")
Call MyProcedure(42)
Call ActiveSheet.Range("A1:A10").Clear
Call Beep
Call CallByName(obj, "SomeMethod", VbCalType.VbMethod)

При последовательном использовании Call быстро становится неприятным, явно избыточным, а замедляет чтение , потому что глаза не могут не остановиться на ключевом слове, а затем мозг говорит: «О, смотри, мы»Звоню что-то здесь ".Я полагаю, что в какой-то момент вы просто перестаете видеть это и просто чувствуете, что что-то выключено, если оно отсутствует.

Подавляющее большинство каждого исполняемого оператора будет вызовом чего-то,где-то, на некотором уровне абстракции - использование Call постоянно делает язык еще более громоздким, чем он есть.

Если Call не на самом деле о согласованности, больше о возможность легко видеть мои собственные пользовательские вызовы процедур ..., которые на данный момент просто цепляются за соломинку, чтобы узаконить архаичную конструкцию, которая не имеет никакого смысла вообще: нет законного использования для Call ключевое слово .

Это единственный "законный" вариант использования:

Public Sub Test()
DoSomething: DoSomethingElse
'vs.
'Call DoSomething: Call DoSomethingElse
End Sub

Private Sub DoSomething() '<~ dead code. can you see why?
End Sub

Private Sub DoSomethingElse()
End Sub

Ключевое слово Call устраняет неоднозначность LineLabel: с ParameterlessProcedureCall, за которым следует : разделитель команд.Единственная проблема в том, что : разделитель инструкций отлично подходит для игры в гольф и втискивает как можно больше исполняемого кода в одну строку кода ... они ужасны для удобства чтения.Кроме того, все согласны с тем, что NEWLINE должно следовать за ; на любом языке с точкой с запятой, , хотя для компилятора имеет смысл игнорировать скачок строки .

Мы пишемкод для людей, чтобы читать и поддерживать, а не только для компиляторов для сборки и запуска.


Устаревший?Говорит кто?

Говорит Я и мой утенок .

Я на 100% уверен, что однажды прочитал в Официальных документах, чтоКлючевое слово устарело.Черт, даже указывает как избыточный .Языки развиваются, VBA не является исключением - даже с невероятно невероятными уровнями обратной совместимости и спустя два десятилетия без каких-либо существенных изменений язык - или, скорее, его практика все еще подвижна, даже если егосопровождающие удалились пообещали просто пусть это будет .

Call - не единственный устаревший токен в VBA, но по сомнительным субъективным причинам, не отличающимся от того, чтолюди используют, чтобы оправдать цепляние за огромную ошибку, которую в этом столетии Systems Hungarian нотация была , ее корни уходят глубоко.

Где защитники Remмаркер комментария?Почему While...Wend все еще вещь, когда Do While...Loop заменяет ее?Кто-нибудь поднимает ошибки с оператором Error, а не через Err.Raise?Вывод сообщений об ошибках с Error$ вместо Err.Description?Объявление типов переменных с очень удобочитаемыми подсказками типа $&%^!#?Кто пишет On Local Error?Зачем использовать Global для вещей, которые действительно Public?

А если явное Call не устарело и «делает код более читабельным», то почему же те же люди не используют явное Let заявления для присвоений значений для точно такой же ясности / ясности?

Я думаю, что давно пора переписать лучшие практики и оставить Call в прошлом вместе с Let, Венгерской нотацией и стенами объявлений в верхней части процедур. Каждое отдельное сообщество программистов уже делало это - только сообщество VBA все еще придерживается «лучших практик» 30-летней давности для совершенно нового кода, а не только для устаревших вещей, написанных в другую эпоху. Я подозреваю, что вполне возможно, что "оценка страха" VBA имеет много общего с этим, даже без учета голой IDE.

Мне бы очень хотелось, чтобы я мог получить ссылку от коллег-старожилов Microsoft MVP Роба Бови и Стивена Буллена и сказать: «Вот, видите, на странице 172 написано ключевое слово call устарело » ( в этом ответе , кажется, упоминается "книга толщиной в два дюйма на VBA, в которой, в основном, говорится, что не используйте ее, если вы не хотите использовать функцию поиска в VBE, чтобы легко находить вызовы в больших проектах"), так что это Возможно, это так, но в любом случае в то время, когда эти гуру по существу определили, какие были лучшие практики, «рефакторинг» был иностранным словом, «модульное тестирование» было экстремальным программированием сумасшедшей идеей - весь ландшафт программирования за последние 20 лет значительно выросла, но VBA остановилась. Время покончить с этим и двигаться вперед.

Говоря о , движущемся вперед ...

"Это облегчает переход на VB.NET"

Предположительно, использование операторов Call облегчает перенос кода на .NET, потому что VB.NET везде будет нуждаться в скобках. С уважением, это волы. Во-первых, потому что то, что вы захотите перенести на VBA-код, это не VB.NET, а гораздо более вероятный TypeScript, если когда-либо произойдет перенос , на самом деле . Если вы вручную копируете код VBA и «переводите» его, чтобы заставить его скомпилировать на целевом языке, вы быстро обнаружите, что отсутствие необходимости обращаться с круглыми скобками - это очень незначительный бонус, поскольку буквально все остальное необходимо переписать, ... включая сброс токенов Call.

Написание небольших специализированных процедур, которые делают очень мало, если вообще больше, чем один, используя уровни абстракции и классы / объекты, уменьшая связь между модулями, улучшая связность в модулях * * * * * * * * * * * * * * * * * поможет вам быстрее портировать ваш код VBA и гарантировать, что перенесенный код будет работать идентично. Call, а круглые скобки - это просто повод, чтобы избавиться от вредной привычки.

5 голосов
/ 08 июня 2019

Я стараюсь избегать Call (и поэтому для меня это амортизируется) по следующей причине - в #VBA я считаю передачу переменной в круглых скобках способом переопределения стандарта ByVal / ByRefуточнение параметров.Что я имею в виду?Рассмотрим следующий пример:

Public Sub TestMe()

    Dim var1 As Long: var1 = 1
    Dim var2 As Long: var2 = 1

    IncrementByVal (var1)
    IncrementByRef (var2)

    Debug.Print var1, var2

End Sub

Public Function IncrementByVal(ByVal a As Variant) As Variant
    a = a + 100
    IncrementByVal = a
End Function

Public Function IncrementByRef(ByRef a As Variant) As Variant
    a = a + 100
    IncrementByRef= a
End Function

Как вы, вероятно, видите, оба значения var1 и var2 возвращают 1, тогда как var2 должно быть 101, насколько оно ByRef,Call -word-type-улучшает эту "особенность" в VBA, но она становится слишком сложной для запоминания, когда скобки переопределяют ByRef, а когда нет, при чтении кода.Таким образом, иметь 3 случая довольно много:

Public Sub TestMe()

    Dim var1 As Long: var1 = 1
    Dim var2 As Long: var2 = 1
    Dim var3 As Long: var3 = 1
    Dim var4 As Long: var4 = 1
    Dim var5 As Long: var5 = 1
    Dim var6 As Long: var6 = 1

    IncrementByVal (var1)           '1
    IncrementByRef (var2)           '1
    IncrementByVal var3             '1
    IncrementByRef var4             '101
    Call IncrementByVal(var5)       '1
    Call IncrementByRef(var6)       '101

    Debug.Print var1, var2
    Debug.Print var3, var4
    Debug.Print var5, var6

End Sub

Public Function IncrementByVal(ByVal a As Variant) As Variant
    a = a + 100
    IncrementByVal = a
End Function

Public Function IncrementByRef(ByRef a As Variant) As Variant
    a = a + 100
    IncrementByRef = a
End Function
2 голосов
/ 08 июня 2019

Я часто использую Call, когда я рефакторинг кода или вырезать новый код, в котором я еще не уверен. Для объяснения, использование Call требует скобок вокруг аргументов и поэтому возвращает значение из функции. Я мог бы хотеть вернуть значение из функции, или я мог бы хотеть передать аргумент по ссылке (ByRef)

Sub Test()
    Dim v

    '* Call requires brackets
    Call NotSureIfThisWillEndUpAsASubOrAFunction(1, 2)

    '* return a value from a Function then need brackets
    v = NotSureIfThisWillEndUpAsASubOrAFunction(1, 2)

    '* if always a sub then no brackets required
    WillAlwaysBeASub 4, 5

    '* but is this really so ugly, why deprecate this?
    Call WillAlwaysBeASub(4, 5)

End Sub

Function NotSureIfThisWillEndUpAsASubOrAFunction(a, b)

End Function

Sub WillAlwaysBeASub(c, d)

End Sub

РЕДАКТИРОВАТЬ: Я думаю, что использование скобок все время (что означает использование Call в качестве ключевого слова для подпрограмм) означает меньше времени на обход кода, снятие скобок и последующее их повторное использование при изменении мнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...