Работа в REPL

REPL - Read Eval Print Loop (Прочитать Выполнить Печатать Повторить) позволяет выполнять команды языка и сразу видеть результат.

  • Для запуска REPL - нужно в консоли выполнить команду julia. Появится приглашение julia>. (Если переменная PATH не указывает путь до julia, то нужно предварить команду julia путем до нее.)
  • Для выхода из REPL нужно набрать CTRL+D в начале строки.
  • Чтобы выполнить команду - нужно ее набрать, к примеру, 1+1 и нажать Enter, появится результат: 2.

В REPL результат последнего выполненного выражения сохраняется в переменной ans. Вне REPL такое поведение будет отключено. Точка с запятой, поставленная после выражения, отключает печать результата выражения в консоль REPL, но переменная ans, все равно, сохраняет результат. Например,

1+2; (Enter)

На экране ничего не напечатается.

ans * 2 (Enter)

на экране появится ответ 6

Вернуться к предыдущей команде, выполненной в REPL можно стрелкой вверх.

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

Справка

Если строго в начале строки набрать знак вопроса ?, то приглашение REPL изменится на help?> - это режим справки. Теперь можно набрать, имя функции (работает автодополнение), например, println, нажать Enter. На экран будет выведена справка по функции.

Модули

Для импорта модулей или подключения файлов используйте одну из команд: import , using, require. (подробнее см. в главе Пакеты, модули).

Команда

in( LOAD_PATH, "." ) || push!( LOAD_PATH, "." )

добавит текущий каталог к списку путей поиска модулей.

Импортировав модуль, можно получить список экспортируемых им имен:

names( имя_модуля_без_кавычек )

Добавив true вторым параметром, вы попросите включить в список и не импортируемые имена.

Автодополнение

Набирая имя импортированной к этому моменту функции, макроса, имя объявленной ранее переменной можно использовать автодополнение. Начните набирать имя функции и нажмите TAB. Если введенный текст однозначно определяет известное имя, слово будет дополнено. Повторное нажатие TAB выведет возможные варианты окончания:

julia> read # <---- здесь, сразу после read два раза нажимаем TAB, внизу видим варианты:
read          readall        readavailable  readbytes!     readcsv        readdlm        readlines      readstring
read!         readandwrite   readbytes      readchomp      readdir        readline       readlink       readuntil
julia> read  # <----- после перечисления вариантов повторяется набранная строка для продолжения ввода, курсор стоит здесь.

Если после имени функции, поставить открывающую скобку и нажать TAB, то будет выведен список выриантов использования этой функции с разным набором аргументов:

julia> open( #<--- два раза TAB
open(fname::AbstractString) at iostream.jl:98
open(fname::AbstractString, rd::Bool, wr::Bool, cr::Bool, tr::Bool, ff::Bool) at iostream.jl:88
open(fname::AbstractString, mode::AbstractString) at iostream.jl:101
open(f::Function, cmds::Base.AbstractCmd, args...) at process.jl:553
open(f::Function, args...) at iostream.jl:111
open(cmds::Base.AbstractCmd) at process.jl:536
open(cmds::Base.AbstractCmd, mode::AbstractString) at process.jl:536
open(cmds::Base.AbstractCmd, mode::AbstractString, other::Union{Base.FileRedirect,IO,RawFD}) at process.jl:536
julia> open(

Если открыть кавычки и начать писать имя существующего файла/каталога, то будет работать автодополнение имен файловой системы:

# julia была запущена из домашнего каталога пользователя

julia> ". # <--- здесь после открывающей кавычки я поставил точку
.bash_history         .cache/                .cpanplus/             .julia_history         .opam/                 .ssh/
.bash_logout          .config/               .gitconfig             .lesshst               .pip/                  .utop-history
.bashrc               .continuum/            .inputrc               .local/                .profile               .viminfo
.bashrc-anaconda3.bak .cpan/                 .julia/                .ocamlinit             .repl.session
julia> ".

Если существует значение типа Dict (Словарь), то автодополнение существующих имен ключей работает после открывающей квадратной скобки и, как минимум, первого символа ключа. Например:

julia> d1 = Dict(:a=>1,:b=>2)
Dict{Symbol,Int64} with 2 entries:
  :a => 1
  :b => 2

# пеперь набираем d1[: и нажимаем два раза TAB:
julia> d1[:
:a :b

пример словаря типа Dict{String,Int64}, здесь имена ключей идут в кавычках:

julia> d2 = Dict("aa"=>123, "ab"=>234, "bb"=>555)
Dict{String,Int64} with 3 entries:
  "bb" => 555
  "ab" => 234
  "aa" => 123

julia> d2["   # <--- здесь тоже нажимаем два раза TAB
"aa" "ab"  "bb"
julia> d2["

# здесь начали писать первую букву ключа:
julia> d2["a 
"aa" "ab"
julia> d2["a

Многострочный ввод

Если введенная команда синтаксически не закончена, например, не поставлена закрывающая скобка или не хватает парных кавычек, то REPL не выполняет команду после нажатия Enter, а ждет продолжения ввода.

# функция min() может возвращать минимальный из переданных ей аргументов

julia> min( # <--- здесь я нажал Enter, произошел перевод строки
       4, # <-- Enter
       5, # <-- Enter
       3 ) # <-- Enter: синтаксически конструкция завершена, что привело к выполнению
3

Когда нужно ввести несколько строк кода без его выполнения, для переноса строки вводите Alt+Enter. Последующее нажатие Enter запустит на выполнение весь введенный текст.

# Alt+Enter использован, чтобы перед определением функции написать doc-строку
julia> "Возвращает полное имя файла .julia_history" # <---Alt+Enter
       history_name() = homedir()*"./julia_history" # <---Enter
history_name
julia>
# теперь получим справку по функции: поставим в начале строки знак вопроса и наберем ее имя: 
help?> history_name  
search:

  Возвращает полное имя файла .julia_history

Прерывание выполнения

Если, набирая длинную команду, вы решили отказаться от ввода, можно нажать Ctrl+C. Ввод будет прерван, а набранный текст не сохранится в истории команд.
Ctrl+C также работает для прерывания долго выполняющейся команды

Оператор |>

Оператор |> позволяет вычисленное слева от него выражение передать в функцию справа от него. Эта функция должна принимать один аргумент. Это удобно тем, что позволяет наращивать вложенные вызовы не прибегая к скобкам. Например:

Длинный-
длинный-
код-
возвращающий-
сложную-
структуру |> dump

Вместо dump может быть, к примеру, println

или

Длинный-
длинный-
код-
возвращающий-
массив |> length

Когда требуется использовать функцию, ожидающую более одного аргумента, то можно на месте создать анонимную функцию, ожидающую один аргумент и подставляющая остальные:

Длинный-
длинный-
код-
возвращающий-
массив-
или итератор |> xs->take(xs,5)

Отображение массивов

Одномерные массывы отображаются в REPL по вертикали:

julia> [1,2,3]
3-element Array{Int64,1}:
 1
 2
 3

Поставив запятую в конце, вы, тем самым, создадите кортеж, и массив будет отображен внутри кортежа (в круглых скобках с запятой) по горизонтали:

julia> [1,2,3],
([1,2,3],)

Ввод символов Unicode

Julia поддерживает символы Unicode в коде. Некоторые функции стандартной библиотеки имеют вторые, более короткие имена с использованием таких символов. Пример: функция isapprox() сравнивает два числа и возвращает true, если они приблизительно равны:

isapprox(0.33333333, 1/3)
true

Функция isapprox() имеет псевдоним - оператор , для ввода которого нужно в REPL набрать \approx и нажать TAB. Приведенное выше выражение может быть переписано так (операторы позволяют инфиксную запись):

0.33333333 ≈ 1/3

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

≈(0.33333333, 1/3)

Набрав в REPL \ и нажав дважды TAB, вы получите список имен, которые заменяются на символы юникода. Не все из них - функции, например Юникод-символ "Венера" (\venus+TAB) не определен, как имя чего-либо, и справка по нему нечего не выдаст.

Файл ~/.juliarc.jl

Если создать в своем домашнем каталоге файл ~/.juliarc.jl , то при каждом запуске julia, будут выполняться все команды, перечисленные в нем.
(Это поведение отключается для машин-воркеров при запуске в режиме кластера. )
Вы можете сделать это любым способом. А в этом примере мы сделаем это прямо из REPL:

# на случай, если julia запущена не из домашнего каталога - перейдем туда:
julia> homedir()|>cd 

julia> open(".juliarc.jl", "w") do wio
           println( wio, """println("Привет! Это твой друг .juliarc.jl. Измени меня.") """ )
       end

julia>

# А потом перезайдем в REPL:
$ julia -q # ключ -q отключает цветной баннер "Julia" при входе в REPL
Привет! Это твой друг .juliarc.jl. Измени меня.
julia>

Ключи запуска julia

Более гибкой альтернативой созданию файла ~/.juliarc.jl может быть указание ключа -e при запуске julia. Например, добавив текущий каталог с помощью переменной окружения в путь поиска модулей, импортируем некий Mymodule и вызовем некую функцию func из него. Нужно помнить, что после -e следует указать -i, чтобы остаться в REPL после выполнения указанных комманд:

JULIA_LOAD_PATH="." julia -e'import Mymodule; Mymodyle.func(123)|>print' -i

Посмотреть полный список ключей запуска можно с помощью команды julia -h.

Другие полезные вещи:

  • Получить тип значения: typeof(3) # напечатает Int64, typeof(3.0) # напечатает Float64.
  • Увидеть тип и структуру значения сложного типа: dump(). К примеру, введите dump( Dates.now() )
  • Поиск документации содержащей подстроку "print": apropos("print")

  • Вывести все глобальные переменные и их типы: whos()

  • Сменить текущий каталог: cd("/home/user1")

  • Вывести имя текущего каталога: pwd()

  • Выполнить файл: include("./file.jl")
  • Очистка пространства имен Main без перезагрузки REPL: workspace(). По умолчанию, все глобальные объявления в REPL находятся в модуле Main. Все, что было объявлено в Main, теперь будет находиться в LastMain.
  • Посмотреть исходный код функции, например, max(), вызываемой с конкретными аргументами 1 и 2: @less(max(1,2)) Функция должна быть импортирована (доступна), и ее исходный код должен находиться в исходном файле (а не определен в REPL).
  • Редактирование файла с исходным кодом: @edit(max(1,2)). Этот способ подходит для нечастого редактирования. Удобнее открыть второй сеанс терминала и редактировать свой исходный код там. @edit - это макрос, который получая выражение, сам ищет его расположение и открывает редактором, соответствующий файл на нужной строке. Функция edit(имя файла, [номер строки]) - прямой вызов редактора.

Если вам не нравится редактор, то (в Linux) выйдите из REPL, выполните в Bash команду export EDITOR=mcedit (или emacs, vim, nano), после чего в этом же bash-сеансе запустите REPL. Теперь edit() и @edit должны открывать указанный редактор. Если все работает, как надо - можно указанную команду назначения редактора записать в один из ваших стартовых файлов, например ~/.bashrc, после чего перезайти в shell.

  • Файл истории команд. Все команды, выполненные в REPL, сохраняются в домашнем каталоге пользователя в файле ~/.julia_history

Как пример, можно, находясь в REPL, определить функцию быстрого вызова на редактирование указанного файла:

Функция edit() уже занята (свободен только один ее метод без аргументов), поэтому, для простоты, назовем функцию ed():

ed() = edit( homedir()*"/.julia_history" )

Теперь вызов ed() приведет к отрытию редактора по умолчанию на этом файле.

  • Вернуться к последней команде, начинающейся с подстроки: начать писать, например, wh и нажать стрелку вверх. Появится whos(), (если до этого в REPL выполнялась такая функция).
  • Поиск введенных ранее команд начиная с последней: набрать CTRL+R и начать писать. По мере набора, будут появляться совпадения. Для получания следующего совпадения по той же строке, нажать еще раз CTRL+R. (Аналогично ведет себя командная оболочка Bash.)

results matching ""

    No results matching ""