Эй, программист!Осторожней со словами!

Сотрудники группы Microsoft Scripting Guys

Во время Гражданской войны в США (а именно, в ходе битве в округе Спотсильвания) генерал «северян» Джон Седжвик (John Sedgwick) рассердился, увидев, что его солдаты прячутся от случайных выстрелов со стороны противника. Согласно легенде, генерал сказал солдатам: «Мне стыдно за вас. С такого расстояния и в слона-то не попадешь!». Спустя несколько мгновений Седжвик вошел в историю как самый старший офицер, убитый в эту войну. Возможно, Седжвик был прав насчет слонов, но вот, к несчастью для себя, насчет генералов ошибся.

Мораль этой истории... ну да: «когда в тебя стреляют — не высовывайся», так ведь? Как это мы не додумались? Вместо этого у нас получилось следующее: «Будь осторожен со словами, которые говоришь: однажды, вернувшись, они могут очень сильно повлиять на твою судьбу». Так было с генералом Седжвиком и со многими другими. К примеру, никто не помнит Томаса Уотсона (Thomas Watson), основателя и на протяжении многих лет главу IBM, как величайшего в американской истории бизнесмена. Зато его помнят как человека, сказавшего: «Возможно, нам удастся продать штук пять компьютеров».

Самое интересное, что доказательств того, что Уотсон на самом деле это говорил, нет. Он скорее процитировал чье-то мнение по данному вопросу. Сейчас это уже неважно. В конце концов, одна мысль о том, что глава IBM мог сказать, что компьютерного рынка не существует, заставляет забыть о каких-то там фактах.

Между прочим, Уотсон говорил: «Чтобы достичь успеха, нужно удвоить частоту отказов». И этому совету наша группа следует безоговорочно.

Ну, по крайней мере, в том, что касается удвоения частоты отказов.

Или вот еще цитата: «Среду Microsoft®.NET Framework нельзя использовать при написании VBScript-сценариев». Это утверждение, конечно, не такое яркое и запоминающееся, как про слона или про пять компьютеров, но оно так же далеко от истины. Да, действительно, среда .NET Framework создавалась прежде всего для написания программ на C# и Visual Basic® и с помощью VBScript нельзя создавать экземпляры ее собственных классов. Но это не значит, что при написании сценариев средства .NET Framework абсолютно недоступны.

Конечно, никто не спорит с тем, что большинство классов .NET Framework недоступны для VBScript-сценариев. Тем не менее, довольно много этих классов имеют оболочки, вызываемые средствами COM, что попросту означает, что у этих классов есть COM-интерфейс, благодаря которому их можно вызывать из сценариев, написанных в том числе и на VBScript. Не верите? Тогда взгляните на рис. 1, где показан раздел HKEY_CLASSES_ROOT реестра. Вы увидите множество различных классов, имена которых начинаются с «System».

Рис. 1. Системные классы реестра

Рис. 1.** Системные классы реестра **(Щелкните изображение, чтобы увеличить его)

Большинство из них являются классами .NET Framework и их экземпляры могут быть созданы средствами VBScript.

Вот так-то!

Все, кто когда-либо приобретал товары, рекламирующиеся по телевизору поздно ночью, подтвердят, что совершенно необязательно делать что-то только потому, что это можно делать (как правило, всегда найдется причина, почему эти товары не продаются в магазинах). Да, в сценарии можно создать экземпляр класса System.ContextMarshalException... Только вот непонятно, кому и зачем это нужно.

Но есть и другие классы .NET Framework. Например, принято считать, что не существует простых методов сортировки элементов списка в сценарии. Для сортировки элементов по алфавиту необходимо использовать несвязный список записей или самостоятельно написать некую хитрую функцию, например функцию с использованием метода пузырьковой сортировки, подобную приведенной ниже (если вы не сможете переварить следующий абзац, пропустите его):

For i = (UBound(arrNames) - 1) to 0 Step -1
    For j= 0 to i
        If UCase(arrNames(j)) > 
          UCase(arrNames(j+1)) Then
            strHolder = arrNames(j+1)
            arrNames(j+1) = arrNames(j)
            arrNames(j) = strHolder
        End If
    Next
Next

Только не расстраивайтесь, мы сами не до конца понимаем, что же такое написали.

Итак, чем в подобной ситуации нам может помочь .NET Framework? Для ответа на этот вопрос давайте рассмотрим очень простой и понятный сценарий:

Set DataList = CreateObject _
      ("System.Collections.ArrayList")

DataList.Add "B"
DataList.Add "C"
DataList.Add "E"
DataList.Add "D"
DataList.Add "A"

DataList.Sort()

For Each strItem in DataList
    Wscript.Echo strItem
Next

Как видите, мы просто создаем экземпляр класса System.Collections.ArrayList среды .NET Framework. Затем используем метод Add для добавления в список пяти элементов. Все это хорошо, но элементы добавлены случайным образом (B, C, E, D, A), а нам нужно, чтобы они располагались в алфавитном порядке (A, B, C, D, E). Теперь нам понадобится процедура сортировки пузырьковым методом, так?

Нет. (Извините за резкость, но «нет» значит «нет».) На самом деле достаточно вызвать метод Sort классаArrayList:

DataList.Sort()

И все. Сортировка элементов производится с помощью всего одной строки.

Нужны доказательства? Вот ведь какая недоверчивая публика. Ладно, мы знали, что здесь найдется Фома неверующий, а то и двое. Именно поэтому в сценарии используется цикл For Each, проходящий все элементы списка и выводящий значения каждого из них на экран:

For Each strItem in DataList
    Wscript.Echo strItem
Next

Следующий вопрос: что мы получим на выходе?

Правильный ответ:

A
B
C
D
E

Замечательно, правда?

Гм, кажется, еще не все в восторге. Говорите, что все это прекрасно, но вам хотелось бы отсортировать значения в обратном порядке, по убыванию? Т.е. вы предпочитаете список от Я до А, а не от А до Я. И вот если мы и такое сможем, то тогда... ну ладно. . .

Нет проблем. Пожалуйста:

Set DataList = CreateObject _
      ("System.Collections.ArrayList")

DataList.Add "B"
DataList.Add "C"
DataList.Add "E"
DataList.Add "D"
DataList.Add "A"

DataList.Sort()
DataList.Reverse()

For Each strItem in DataList
    Wscript.Echo strItem
Next

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

DataList.Reverse()

Видите? После сортировки по возрастанию мы вызвали метод Reverse, который — представьте себе — расставляет элементы массива в обратном порядке. Что это дает? На выходе это дает следующее:

E
D
C
B
A

Впечатляет, да?

Подождите-ка. Все еще лучше. Вы когда-нибудь пытались удалить элемент из массива в сценарии VBScript? Не бойтесь, мы не будем предлагать вам это сделать. Вместо этого, сейчас вы увидите, как просто удалить элемент из класса ArrayList. Не нравится буква «D»? Так давайте от нее избавимся. Вот сценарий, который создает список массивов, сортирует его, а затем удаляет элемент D:

Set DataList = CreateObject _
  ("System.Collections.ArrayList")

DataList.Add "B"
DataList.Add "C"
DataList.Add "E"
DataList.Add "D"
DataList.Add "A"

DataList.Sort()
DataList.Remove("D")

For Each strItem in DataList
    Wscript.Echo strItem
Next

Опять-таки, обратите внимание на коротенькую строчку кода сразу за методом Sort:

DataList.Remove("D")

Здесь мы использовали метод Remove, чтобы удалить элемент, значение которого равно D. И вот что мы получаем на выходе:

A
B
C
E

Аста ла виста, D!

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

Верите или нет, но мы показали вам лишь малую часть возможностей работы с массивами .NET Framework. Более подробная информация приведена на веб-узле arraylist entry in the .NET Framework SDK (на английском языке).

Нужен ли класс ArrayList для написания сценариев? Скажем так, после его изучения мы не можем с уверенностью сказать, что встроенный VBScript-массив необходим, по крайней мере, для работы с такими простыми списками элементов как рассмотренные выше.

Но надо признать, что наша группа, Scripting Guys, не проводила исчерпывающего исследования .NET Framework для выяснения того, какие классы могут оказаться полезными для написания сценариев, а какие нет. Этим мы как раз занимаемся в данный момент. Вы, между тем, можете сами начать изучатьПакет средств разработки программного обеспечения.NET Framework SDK (на английском языке). Складывается ощущение, что в пакете SDK программист, пишущий сценарии, всегда найдет для себя что-то новое и интересное.

Хотите пример? Как насчет генератора случайных чисел? Хотите получить случайное число от 1 до 100 с помощью генератора случайных чисел VBScript? Пожалуйста. Просто используйте код вроде этого:

Randomize
Wscript.Echo Int((100 - 1 + 1) * Rnd + 1)

Запомнили формулу? Нет? Ну и ладно. Оказывается, класс System.Random среды .NET Framework намного проще и более интуитивно-понятный:

Set objRandom = CreateObject("System.Random")
Wscript.Echo objRandom.Next_2(1,100)

Скорее всего, вы уже и сами все поняли. Однако мы все-таки коротко прокомментируем происходящее, потому что главный редактор TechNet Magazine считает, что ведущий колонки обязан каждый месяц хоть что-то написать. (Такой порядок выше нашего понимания.)

Как видите, мы создаем экземпляр класса System.Random и затем вызываем метод Next_2, передавая ему два параметра:

  • 1 — это нижняя граница интервала (помните, мы хотели получить случайное число от 1 до 100).
  • 100 — верхняя граница.

Вот и все, что нужно сделать.

Похоже, у нас есть время на последний вопрос из зала. Да, пожалуйста, вот вы, молодой человек в зеленой рубашке. Кто же это сказал, что при написании сценариев у нас нет доступа к .NET Framework? Ну, если совсем честно, когда мы начинали, мы... ой, похоже, наше время истекло. До встречи через месяц!

Веселые деньки

Скоро февраль, что означает только одно. Нет, не День Святого Валентина. И не День защитника Отечества. Неужели День сурка? Да нет, чем ближе февраль, тем ближе зимний чемпионат по программированию 2007 (Winter Scripting Games), самые главные и, возможно, единственные в своем роде международные соревнования по написанию сценариев. В этом году игры обещают быть еще масштабнее, еще лучше, чем когда-либо. На этот раз у нас будет четыре группы:

  • VBScript, начинающие
  • VBScript, мастера
  • Windows PowerShell™, начинающие
  • Windows PowerShell, мастера

Более подробная информация приведена на веб-узле: 2007 Winter Scripting Games (на английском языке).

Что, простите? Да, спасибо. Конечно... и вас с Днем сурка.

Загрузить Windows PowerShell сейчас

Windows PowerShell 1.0 теперь доступен для загрузки. Бесплатно! Разве можно упустить такой шанс? Загрузите PowerShell и начните пользоваться им уже сегодня.

Сотрудники группы Microsoft Scripting Guys работают... ну хорошо, числятся в корпорации Майкрософт. Когда они не играют в бейсбол, не тренируют бейсбольную команду, не смотрят бейсбол и не занимаются другими делами, они ведут проект Script Center в журнале TechNet. Веб-узел проекта: www.scriptingguys.com (на английском языке).

© 2008 Корпорация Майкрософт и компания CMP Media, LLC. Все права защищены; полное или частичное воспроизведение без разрешения запрещено.