Snusmumriken
1. У тебя неправильный синтаксис. Отсутствуют вызовы функций, которые подразумевают двоеточия.
local foo = obj:bar2():bar3()
Во-вторых, каждая функция bar2/bar3 должна возвращать self, дабы такая цепочка работала. Ну, например со строками оно работает потому что каждый раз возвращается новая строка, у которой есть те же методы.
local str = 'qwerty'
str = str:gsub('[q-e]', '.'):match('%..-')
2. Да, оно примерно так и работает. Правда, если вернуться должен объект, по мне лучше возвращать "пустой" объект. Ты ведь его методами/параметрами собрался пользоваться?
local foo = obj:bar2():bar3() or Obj:new()
mva
а ещё за local внутри if (как минимум в данном контексте) стоит насиловать раскалённой кочергой
mva
потому что войдёт в привычку, а потом по недосмотру будут контексты скакать
mva
и будет "ой, что за херня происходит"
Snusmumriken
Кстати да.
local foo=obj():bar2():bar3()
if not foo then
local foo={}
end
Вот это вот local foo = {} останется только внутри скоупа if, снаружи оно не изменится. Разберись со скоупами.
Andrey
1. У тебя неправильный синтаксис. Отсутствуют вызовы функций, которые подразумевают двоеточия.
local foo = obj:bar2():bar3()
Во-вторых, каждая функция bar2/bar3 должна возвращать self, дабы такая цепочка работала. Ну, например со строками оно работает потому что каждый раз возвращается новая строка, у которой есть те же методы.
local str = 'qwerty'
str = str:gsub('[q-e]', '.'):match('%..-')
2. Да, оно примерно так и работает. Правда, если вернуться должен объект, по мне лучше возвращать "пустой" объект. Ты ведь его методами/параметрами собрался пользоваться?
local foo = obj:bar2():bar3() or Obj:new()
коллеги про локал внутри ифа - если там поставить не локал - оно станет global или оно будет local на уровень выше ?
про синтаксис да, хорошо - тогда как мне сделать что если вернулся nil - кроме того что инициализировать пустую переменную еще print -ом вывести в лог что вернулся nil вместо массива ?
Snusmumriken
Разберись со скоупами.
Подсказка: если нет local — оно ищет ближайшую переменную с таким именем по ходу выше и меняет, создавая новую в глобал-скоупе если не нашло. Если есть local — создаёт новую переменную в этой точке, которая доступна только в этом скоупе и более глубоких, расположенных ниже.
Andrey
оно ищет ближайшую а ее там нет потому что в нее вернулся nil ...
Andrey
а теперь вопрос - метод возвращает в локальную переменную либо nil либо заполненный массив
в первом случае мне надо вывести алерт и перетпределить на пустой массив
во втором оставить как есть
Andrey
как мне это сделать
Snusmumriken
Если нужен алёрт — очевидно делать if.
Andrey
да, но я внутри этого ифа кого переопределю на пустой массив ?
Andrey
а эта темная магия не выдаст алерт в лог
Snusmumriken
Snusmumriken
Только если alert() возвращает true
Snusmumriken
Да
Andrey
Ооо!
Andrey
Спасибо!
Snusmumriken
Со скоупами разобрался, теперь пришло время разбираться с or/and.
Snusmumriken
Сам разберётся, когда нагромоздит or-and'ов, а потом будет в этом копаться.
Andrey
а сверху t не существует
Andrey
и оно глобально присвоит
Andrey
внутри метода :)
Andrey
ну мне надо внутри метода :) видимо я не до конца обьяснил
mva
а где же проверка что sometable вообще таблица? :)
Snusmumriken
function foo(a, b)
a = a or 0
b = b or 0
return a + b
end
print( foo(10) ) --> 10
print( foo() ) --> 0
Аргументы функции — фактически, локальные переменные, созданные в начале функции.
Andrey
Andrey
в начале функции
Andrey
то нет никакого a
Snusmumriken
Не nil а то значение которое пришло в функцию.
Snusmumriken
Вот тебе допзадание.
local a = 10
do
local a = nil
a = 20 + 10
end
print(a)
Andrey
30
Snusmumriken
Хех, 10.
Andrey
эээ
Andrey
что правда ?
Snusmumriken
Ага.
Andrey
я не за компом
Snusmumriken
Должно быть то же самое. Оно же не соберётся мусорщиком пока доступно.
Andrey
ггг
Snusmumriken
За внезапные исчезновения значений от сборки может отвечать только метатаблица __mode, а это нимношк более продвинутый уровень, подразумевается что люди понимают что делают.
Snusmumriken
эээ
Карочи, оно видит что имя локальной переменной было определено в той точке, поэтому будет использовать его. Луям не важно, есть ли у этой переменной значение. Главное чтобы она _была_. Поэтому, например, у меня есть вот такой вот код
function cwait(time, cb, ...)
time = os.time() + time
local remains
while os.time() < time do
remains = time - os.time()
if cb then cb(remains, ...) end
coroutine.yield()
end
end
И местный local remains вполне работает.
Andrey
секунду т.е. local a = nil все таки ее инициализирует ?
Snusmumriken
Ага. Даже без "= nil".
Andrey
Отлично
Snusmumriken
Видишь в примере local remains? Это значит что все последующие "глобальные" присваивания внутри этого скоупа будут направлены в эту точку, если кто-то не перекроет.
Andrey
Супер
Andrey
а кстати print (remains) или not remains тогда что вернет
Snusmumriken
local remains
print(remains) —> nil
print(not remains) —> true
print(not not remains) —> false
Andrey
Все, теперь у меня в голове все на местах
Snusmumriken
Всё очень логично, если чуть-чуть поэкспериментировать.
Andrey
Да, только это неочевидно
Snusmumriken
Поэтому нужно экспериментировать : )
Andrey
не очень очевидно я бы сказал :) Спасибо!
Andrey
А стереть переменную как то можно ?
Andrey
так что бы совсем в окружении не видеть
Andrey
обратный local
Snusmumriken
Да, просто так определять глобальные переменные нельзя, только локальные.
Ну там, сделать глобальный вариант "local remains" не получится, тебя не поймут.
Стереть — присвоить nil, но точка остаётся.
Стереть так чтобы в данном скоупе было обращение в более высокие окружения — нельзя.
Andrey
а обратиться к той же переменной в более высшем скоупе ?
Snusmumriken
Если хочется докопаться прям до глобал-скоупа — можно нагло воспользоваться _G. Это — таблица, в которой содержатся все-все глобальные переменные.
x = 30
do
local x = 10
_G.x = 20
end
print(x) --> 20
Snusmumriken
А если хочется обратиться к той же переменной в более высоком скоупе — просто назови её иначе, изи ))
Локалы перекрывают доступ к более высоким штукам с тем же именем, так что просто не перекрывай.
mva
Andrey
Andrey
и мне хоч узнать что там на уровень выше было
Snusmumriken
Если это рекурсия, то всё становится куда веселее. И тут обратный local приводил бы к кошмарным последствиям для твоей психики.
mva
няп, в lua всегда можно сделать без рекурсии
Snusmumriken
Всё всегда можно сделать без рекурсии, но рекурсия имеет ряд определённых приятностей.
Andrey
mva
алсо, если хочется делать рекурсию (и иметь доступ к скоупу уровня выше), то делаешь отдельную функцию для рекурсии и передаёшь в неё скоуп
Snusmumriken
обход дерева ?
Легко. У тебя есть "указатель на текущую ноду" и на цепочку предыдущих, спускаешь его в глубину, в ширину и так далее. Условно два цикла для спуска глубже и ухода вширь. Подъём вверх автоматический, если достигли дна.
mva
volia!
Andrey
Andrey
Ну или так - для примера из прошлой жизни есть 64 тысячи отделений ПР (Почта России) допустим они друг другу подчиняются кроме какой нить республики у всех есть id - индексы
Andrey
и все сука древовидные
Andrey
А надо быстро исключить Иркутскую область
Snusmumriken
Andrey
Snusmumriken
Карочи, это довольно тривиальная задача, особенно со стеком. Но многие рекурсивные алгоритмы становятся весьма нетривиальными при их разворачивании.
Andrey
Ну вы меня до конца то дослушаете ?
Andrey
На вход массив с почтлвывыми отделениями
Snusmumriken
И дерево индексов.