Форум программистов, компьютерный форум, киберфорум
Наши страницы
Lua
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
Nikropolb
55 / 55 / 12
Регистрация: 25.06.2012
Сообщений: 286
Записей в блоге: 1
1

В чем разница записей

07.11.2015, 23:02. Просмотров 707. Ответов 12
Метки нет (Все метки)

Всем привет. Есть ли какая-то разница в этих двух способах определения поля таблицы как метода? Если есть, то при каких условиях какой метод будет лучше?

C++
1
2
3
tbl.a = function( x ) print( x ) end
 
function tbl.a( x ) print( x ) end
Добавлено через 2 часа 3 минуты
Вопрос №2: Объекты объявленные в теле функции по дефолту считаются локальными относительно области видимости самой функции или нужно явно указывать local?
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.11.2015, 23:02
Ответы с готовыми решениями:

int const и const int в чем разница этих записей
Попалась мне тут программа для выборочно сортировки, с ней все в принципе ясно,...

Разница в времени записей в календаре пользователя
Domino 9.0.1 Формат баз R9 Шаблон StdR9Mail/ru Добрый день . В календаре...

в чем разница?
вот такая вот конструкция (условие)?ложь:истина дает такой же результат...

В чем разница
Здравствуйте подскажите чем они отличаются и скажется ли это на ФПС 1....

В чем разница?
В чем разница @Ajax.ActionLink(item.Brak, "GetBrak", null, new AjaxOptions {...

12
vantfiles
38 / 35 / 19
Регистрация: 07.05.2013
Сообщений: 133
08.11.2015, 00:30 2
Лучший ответ Сообщение было отмечено Nikropolb как решение

Решение

В данном случае имхо разницы никакой.
Разница может появится при использовании self.

Например:

C++
1
2
3
tbl = { x = 100 }
function tbl:tst() print( self.x ) end -- так можно
tbl:tst = function() print( self.x ) end -- так нельзя
Если функции небольшие, бывает удобно писать так:

C++
1
2
3
4
5
tbl = {
  f1 = function() return 1 end,
  f2 = function() return 2 end,
  f3 = function() return 3 end,
}
Если же функции большие по тексту, то удобнее так:

C++
1
2
3
4
5
6
7
8
9
10
11
tbl = {}
 
function tbl.f1()
-- много текста
end
function tbl.f2()
-- много текста
end
function tbl.f3()
-- много текста
end
И наконец вариант с присвоением используется в неименованных функциях:

C++
1
2
3
4
5
6
7
tbl = {
  [1] = function() return 1 end,
  [2] = function() return 2 end,
  [3] = function() return 3 end,
}
 
x = tbl[1]()
Добавлено через 1 час 9 минут
>Вопрос №2.....

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
x = 123
 
function test1()
    x = 456
end
 
test1()
 
print( x ) -- 456, потому что в функции произошло присвоение глобальной переменной
 
function test2()
    local x = 789
end
 
test2()
 
print( x ) -- 456, потому что присвоение касалось локальной переменной
1
Nikropolb
55 / 55 / 12
Регистрация: 25.06.2012
Сообщений: 286
Записей в блоге: 1
08.11.2015, 00:32  [ТС] 3
Большое спасибо!
0
ProgJ
87 / 85 / 10
Регистрация: 20.11.2008
Сообщений: 724
08.11.2015, 14:44 4
Ещё по поводу разницы
В случае использования рекурсии в локальных функциях, т.е. видимости локальной функцией себя самой
Вариант
local f=function() f() end
не является рекурсией. Тут внутри f или глобальная или определённая ранее локальная (upvalue)
Для рекурсии локальных функций делают или так
local f;
f=function() f() end
или так
local function f() f() end
1
Nikropolb
55 / 55 / 12
Регистрация: 25.06.2012
Сообщений: 286
Записей в блоге: 1
08.11.2015, 18:20  [ТС] 5
ProgJ
Спасибо!

Еще вопрос. Где я допустил ошибку? При добавлении поля, и его чтении методы в __index, и __newindex не вызываются.

C++
1
2
3
4
5
6
7
local tbl = {}
 
tbl.__index    = function( _table, _index ) print( "Index " .. tostring( _index ) ) end
tbl.__newindex = function( _table, _index, _value ) print( "New " .. tostring( _index ) ) end
 
tbl[ 1 ]  = 3
local var = tbl[ 1 ]
Добавлено через 48 минут
Но если записать в виде описанном ниже то работает как надо! Почему так?

C++
1
2
3
4
5
6
7
8
9
10
local metaTbl = {}
local tbl     = {}
 
metaTbl.__index    = function( _table, _index ) print( "Index " .. tostring( _index ) ) end
metaTbl.__newindex = function( _table, _index, _value ) print( "New " .. tostring( _index ) ) end
 
setmetatable( tbl, metaTbl )
 
tbl[ 1 ]  = 3
local var = tbl[ 1 ]
Добавлено через 12 минут
В lua нельзя задавать поведение таблицы в "специальных случаях" на прямую? Обязательно нужна дополнительная таблица с реализацией нужного функционала?
0
vantfiles
38 / 35 / 19
Регистрация: 07.05.2013
Сообщений: 133
08.11.2015, 22:30 6
В lua нельзя задавать поведение таблицы в "специальных случаях" на прямую? Обязательно нужна дополнительная таблица с реализацией нужного функционала?
Именно так. В первом случае получилась обычная таблица с тремя полями, индексами которых служат "__index" "__newindex" и 1.

Вот простенький скрипт, позволяющий выводить таблицы на "чистую воду":

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
dbg = {}
 
function dbg.print_t( t )
 
   if t then
      for k,v in pairs( t ) do
          print( k, "-", v )
      end
   else
      print( "...empty." )
   end
 
end
 
function dbg.dump( t )
 
   print( "table: ", t )
   dbg.print_t( t )
 
   print( "meta: " )
   dbg.print_t( getmetatable( t ) )
 
end
1
Nikropolb
55 / 55 / 12
Регистрация: 25.06.2012
Сообщений: 286
Записей в блоге: 1
09.11.2015, 13:15  [ТС] 7
vantfiles
Спасибо!

Работая с мета-таблицами заметил странное поведение.
Если установить мате-таблицу в таком порядке инструкций то функции __index, и __newindex не будут вызываться.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
local meta = {}
local der  = {}
 
meta.__index    = function( _table, _index ) print( "Index" )  end
meta.__newindex = function( _table, _index, _value ) print( "Change" ) end
 
-- Strange zone
der.x = 10
der.y = 20
 
setmetatable( der, meta )
-- Strange zone
 
print( der.x )
print( der.y )
Но если переписать инструкции, которые находятся между комментариями --Strange zone, след. образом, то получим ожидаемый результат. Почему так?

C++
1
2
3
4
5
6
-- Strange zone
setmetatable( der, meta )
 
der.x = 10
der.y = 20
-- Strange zone
Добавлено через 7 минут
В первом случае я ожидаю вывод "Index Index", а в итоге ничего.
0
vantfiles
38 / 35 / 19
Регистрация: 07.05.2013
Сообщений: 133
09.11.2015, 14:53 8
Все как обычно очень просто:

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

Вариант 1:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
local meta = {} -- создали таблицу
local der  = {} -- создали таблицу
 
meta.__index = function( _table, _index ) print( "Index" )  end
-- в таблице meta создали функцию с именем __index
 
meta.__newindex = function( _table, _index, _value ) print( "Change" ) end
 
der.x = 10 -- в таблице der создали индекс x
der.y = 20 -- в таблице der создали индекс y
 
setmetatable( der, meta ) -- прикрепили к der метатаблицу meta
-- ( с этого момента метаметоды могут быть вызваны)
 
print( der.x ) -- обращение к существующему индексу.
-- Метаметод не вызывается, функции print возвращается значение 10,
-- которое она и выводит
 
print( der.y ) -- тот же случай
Вариант 2:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
local meta = {}
local der  = {}
 
meta.__index    = function( _table, _index ) print( "Index" )  end
meta.__newindex = function( _table, _index, _value ) print( "Change" ) end
 
setmetatable( der, meta ) -- в таблице der пусто, но метаметоды теперь "на взводе"
 
der.x = 10 -- обращение к несуществующему индексу x c попыткой присвоить значение,
-- вызывается метаметод __newindex и выводит "Change"
der.y = 20 -- то же для y
 
-- Важный момент - в метаметоде __newindex никаких действий кроме вывода текста нет.
-- Поэтому индексы x и y не созданы и значения им не присвоены.
 
print( der.x ) -- обращение к несуществующему индексу.
-- Вызывается метаметод __index и выводит "Index".
-- Поскольку в метаметоде никакое значение не возвращается,
-- в функцию print попадает значение nil, которое она и выводит.
 
print( der.y ) -- тот же случай
1
Nikropolb
55 / 55 / 12
Регистрация: 25.06.2012
Сообщений: 286
Записей в блоге: 1
09.11.2015, 17:30  [ТС] 9
vantfiles
Понял. Спасибо разъяснения!

Добавлено через 2 часа 6 минут
Практикуя пседво ООП наткнулся на проблему.
Имеем следующий код.

Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
---------- UTILS ----------
local function Extend( _child, _parent )
 
    setmetatable( _child, { __index = _parent } )
end
 
---------- PARENT ----------
local function Factory_Base()
 
    Base          = {}
    Base._private = {}
    
    ---------- PRIVATE ----------
    Base._private.x = 0.0
    Base._private.y = 0.0
    
    ---------- PUBLIC ----------
    function Base:GetX() return self._private.x end
    function Base:GetY() return self._private.y end
    
    function Base:SetX( _x ) self._private.x = _x end
    function Base:SetY( _y ) self._private.y = _y end
    
    return Base
end
 
---------- CHILD ----------
local function Factory_Derived()
 
    Base             = Factory_Base()
    Derived          = {}
    Derived._private = {}
    
    ---------- PRIVATE ----------
    Derived._private.z = 1.0
    Derived._private.w = 1.0
    
    ---------- PUBLIC ----------
    function Derived:GetZ() return self._private.z end
    function Derived:GetW() return self._private.w end
    
    function Derived:SetZ( _z ) self._private.z = _z end
    function Derived:SetW( _w ) self._private.w = _w end
    
    ---------- OPERATORS OVERLOADING ----------
    Base.__add = function( _left, _right ) return _left:GetX() + _right:GetY() end           
    Base.__mul = function( _left, _right ) return _left:GetZ() * _right:GetY() end
 
    ---------- INHERITANCE ----------
    Extend( Derived, Base )
    
    return Derived
end
 
---------- EXAMPLE ----------
 
local derived = Factory_Derived()
 
print( derived.GetX() )
Вывод будет nil. Как я обнаружил, относительно derived в методе GetX self это тот самый derived, а не Base.
Есть ли красивые решения как сделать так что-бы self указывал на Base таблицу?
0
vantfiles
38 / 35 / 19
Регистрация: 07.05.2013
Сообщений: 133
09.11.2015, 18:27 10
У меня ошибка в строке 18.
Кстати, какую версию Луа мы пользуем?
0
Nikropolb
55 / 55 / 12
Регистрация: 25.06.2012
Сообщений: 286
Записей в блоге: 1
09.11.2015, 18:47  [ТС] 11
Случайно в вызове метода поставил . а не :
Правильный вызов.

Pascal
1
print( derived.GetX() )
Версия 5.3

Добавлено через 6 минут
Pascal
1
print( derived:GetX() )
0
vantfiles
38 / 35 / 19
Регистрация: 07.05.2013
Сообщений: 133
14.11.2015, 04:45 12
Вопрос оказался неожиданно сложнее, чем казалось на первый взгляд.
Если дело не срочное, я над ним еще чуток подумаю.
0
Nikropolb
55 / 55 / 12
Регистрация: 25.06.2012
Сообщений: 286
Записей в блоге: 1
15.11.2015, 13:00  [ТС] 13
vantfiles
Буду рад любым советам!
0
15.11.2015, 13:00
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.11.2015, 13:00

В чем разница?
На днях решил докупить себе жесткий диск и увидел такое.(1 ТБ Жесткий диск WD...

В чем разница?
Может кто подскажет в чем разница между двумя действиями: Хочу в АК удалить...

В чем разница?
В чем разница между компонентом и модулем?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru