Работа в 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.)