BeanShell

Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 00:51, 9 июня 2016.
BeanShell
Парадигма Объектно-ориентированный, скриптовый
Спроектировано JCP
Печать дисциплины Динамическая типизация, строгая типизация
Платформа JVM
Лицензия GNU Lesser General Public License
Портал: http://www.beanshell.org/

BeanShell - (произносится [ biːn ʃel ])это небольшой, бесплатный, встраиваемый интерпретатор кода java с функциями скриптового языка, написанного на Java. BeanShell динамически выполняет стандартный синтаксис Java и расширяет его с помощью общих сценариев, такими как динамическая типизация, команды, и замыкания, как в языках Perl и javascript.

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

BeanShell-это небольшой и встраиваемый, так что вы можете вызывать BeanShell функции из ваших приложений java, выполненяя код динамически во время выполнения или обеспечивая расширяемости вашим приложений. Альтернативно, вы можете использовать автономный BeanShell скрипты для управления java-приложениями; работать с объектами Java и интерфейсами API динамически. BeanShell написан на Java и работает в одной виртуальной машине, что и приложение, вы можете свободно передавать ссылки на "живые" объекты в скриптах и возвращать их в виде результатов.

Короче, BeanShell динамически интерпретируемый java, плюс скриптовый язык.

Возможности языка

  1. позволяет определять функции, которые могут быть вызваны из скрипта
  2. позволяет исполнять код, написанный для компилятора Java, а также код BeanShell может быть скомпилирован с помощью Java-компилятора.
  3. благодаря предыдущим возможностям, может и используется для написания тестов и отладки
  4. BeanShell предоставляет простой API для интеграции
  5. может быть использован в режиме командной строки, без графического окружения

История появления BeanShell

Первые версии BeanShell (0.96, 1.0) были выпущены Патриком Нимейера в 1999 году, когда последовал целый ряд версий. BeanShell 1.3.0 был выпущен в августе 2003 года. Версия 2.0b1 был выпущен в сентябре 2003 года, кульминацией которых стала версия 2.0b4 в мае 2005 года, которая по состоянию на январь 2015 новейший релизе, размещенном на официальном веб-страницу. BeanShell была включена в Linux-дистрибутива Debian с 1999 года. BeanShell переживает стандартизацию, осуществляемую сообществом java (ПСП), согласно спецификации jsr 274. Java функция repl (JShell) в настоящее время нацелено для Java 9. [9]

Форк BeanShell, BeanShell2, был создан в мае 2007 года компанией Google. В beanshell2 проект внес ряд исправлений и улучшений для BeanShell. По состоянию на январь 2015, последняя версия beanshell2 является v2.1.

В декабре 2012 года, в соответствии с предложением принять BeanShell как Apache инкубатор проекта, BeanShell получило лицензию на программное обеспечение Apache Foundation и мигрировал в Apache, изменение лицензии по лицензии Apache 2.0. Проект был принят, и по прогнозам, станет частью Apache. Для Windows автоматизированный установщик, BeanShell был создан в 2013 году.

Синтаксис языка BeanShell

Язык программирования Beanshell включает в себя большинство конструкций языка Java. Стандартные конструкции Java поддерживаются Beanshell включая связывание переменных, вызовы методов, математические выражения, циклы и т.д.

Первая программа

Выводит сообщение на консоль:

 
 helloWorld() { 
     print("Hello World!");
 }
 helloWorld();

Импорт классов

По-умолчанию, BeanShell импортирует все Java классы при запуске. Однако вы можете импортировать дополнительно классы, используя стандатный Java синтаксис импорта, например:

  import mypackage.*;

или

  import mypackage.MyClass;

Объявление переменных

BeanShell позволяет создавать специальные script-variable(с динамической типизацией). В отличие от стандартных java-переменных, которые можут ссылаться на объекты только определенного типа, scritp-variable может ссылаться на любой тип объекта, включая примитивные типы, такие как int и boolean. Вы создаете script-variable, объявив ее с или без описателя типа. Если включить спецификатор типа, то переменная может ссылаться на значения только указанного типа. Если Вы не укажете тип, переменная может ссылаться на значения любого типа. Например, следующий оператор:

foo = new Button();

создает нетипизированный скрипт переменную с именем Foo и присваивает ему объект типа Button. Вы свободны, чтобы впоследствии присвоить Foo любой другой тип объекта. Примеры объявлений:

 // указываем тип
 Hashtable hashtable = new Hashtable();
 Date date = new Date();
 int value = 4;

и

 // опускаем тип
 hashtable = new Hashtable();
 date = new Date();
 value = 4;

Переменные с неопределенным значением

Вы можете сравнить переменную с значением void, чтобы убедиться, что переменная неопределена:

    if ( foobar == void )
        // undefined

Вы можете возвращать определнную переменную в неопределнном состоянии используя команду unset():

    a == void;  // true
    a = 5;
    unset("a"); // note the quotes
    a == void;  // true

Объявление скриптовых методов

BeanShell позволяет определить и использовать специальный тип метода, называемый методом-сценария. Сценарий-методы отличаются от стандартных методов java следующим образом:

  • скрипт-методы являются методами неявной типизации объекта
  • сценарий-методы могут быть определены, чтобы принимать и возвращать значения любого типа
  • сценарий-методы можно определить в других методах скрипта

Может использоваться стандартный синтаксис Java для объявления метода-скрипта, который принимает и возвращает конкретные типы. Например, следующий код

int addTwoNumbers(int a, int b) {
  return a + b;
}

определяет метод, называемый addTwoNumbers, который принимает и возвращает значения типа int. Следующий пример:

int а = addTwoNumbers( 5, 7 );

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

add( а, b ) {
  return a + b;
}

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

Неявные объекты

Методы и переменные, определенные сценарием методом считаются методами и полями неявного объекта. Зарезервированные идентификаторы, это, super, и global, ref, соответственно, к текущему объекту, вызывающего объекта, и глобальный объект. Метод может получить доступ к любой переменной или методу в этих областях путем указания имени переменной с именем соответствующего неявного объекта.

 a = 42;
    foo() {
        a = 97;
        print( a );
        print( this.a );
        print( super.a );
    }
    foo();  // prints 97, 97, 42

Сценарий-метод может возвратить неявный объект, тем самым позволяя вызывая скрипт для доступа к переменным и методам, определенным методом, используя стандартную java "." нотации. Например,

    foo() {
        int a = 42;
        bar() {
            print("The bar is open!");
        }
        
        bar();
        return this;
    }

    obj = foo();     // выведет "the bar is open!"
    print ( obj.a )  // 42
    obj.bar();       // выведет "the bar is open!"

Ссылка this

Ссылка this играет огромную роль в скриптовых языках. При определении переменных в блоке(функции), эти переменных связаны с блоком и могут быть полчены через ссылку на объект, которому принадлежат:

 foo() {
     int bar = 42;
     return this;
 }
 fooObject = foo();
 print( fooObject.bar ); // выведет 42!

Кроме this объекты могу принадлежать следующим областям видимости: 'this', 'super' и 'global'.

Синхронизация

Для синхронизации операций в блоке или методе используется ключевое слово: synchronized. Примеры:

 synchronized ( this ) { }   
 synchronized int foo () { }   
 synchronized int bar () { }   
 int gee() {
       synchronized( super ) { } 
 }

Многопоточность

Для того, чтобы можно было воспользоваться многопоточным выполнением наших скриптов, нужно реализовать метод run() и передать ссылку на этот объект в конструктор класса Thread:

 foo() {
    run() {
       // do work...
    }
    return this;
 }
 foo = foo();
 // Запуск двух потоков foo.run()
 new Thread( foo ).start();
 new Thread( foo ).start();

Список литературы