Topic: Точка _G: внутренности движка опасно лежат в глобале

Собственно, в чём проблема. Ряд объектов, используемых сугубо движком и безразличных пользователю, лежит прямо в глобальной области видимости, то есть в таблице _G. Если в голом интерпретаторе lua в ней всего 40 вхождений, то в INSTEAD с совместимым API уже 340, а с API 1.4.0 -- все 354*.
* версия самого INSTEAD 1.4.2

Разумеется, эти цифры включают собственно пользовательский интерфейс INSTEAD, но остальным объектам не место в глобале. Если, скажем, перезапись документированной функции можно отследить, обнаружив знакомое имя в неположенном месте, то по совпадению заменив что-нибудь из внутренностей движка, можно потратить немало времени на устранение косяка.

INSTEAD держит курс на перенос всей ботвы внутрь сакрального объекта stead, но путь ещё не завершён.

Оставляю здесь отчёт о сравнении окружений. В совместимом INSTEAD помимо стандартных 40 имён обнаружены:

add_sound
allocator
allocator_save
autosave
back
bit_add
bit_and
bit_div
bit_idiv
bit_imul
bit_mod
bit_mul
bit_not
bit_or
bit_shl
bit_shr
bit_signed
bit_sub
bit_unsigned
bit_xor
call
call_bool
callpop
callpush
call_value
cat
cctx
change_pl
check_list
check_object
check_player
check_room
clearargs
clearvar
code
dec_music_loop
delete
deref
dialog_empty
dialog_enter
dialog_look
dialog_phrase
dialog_poff
dialog_pon
dialog_prem
dialog_pseen
dialog_punseen
dialog_rescan
dialog_scene
disable
disable_all
disabled
dlg
doencfile
do_ini
do_savegame
drop
dropf
enable
enable_all
exist
fmt
font_free
font_load
font_scaled_size
for_each
for_each_codeblock
for_each_list
for_each_object
for_each_player
for_each_room
for_everything
from
game
gamefile
game_ini
game_life
game_load
game_save
game_start
game_step
get_autosave
get_gamepath
get_inv
get_music
get_music_loop
get_picture
get_savepath
get_sound
get_sound_chan
get_sound_loop
get_steadpath
get_ticks
get_title
get_ways
go
goto
have
here
hook
iface
ilist
img
imgl
imgr
inext
inherit
input
instead
instead_version
inv
isCode
isDialog
isDisabled
isEnableAutosave
isEnableSave
isFading
isForcedsc
isForSave
isList
isMenu
is_music
isObject
isPhrase
isPlayer
isRemoved
isRoom
isSceneUse
is_sound
isStatus
isVroom
isXaction
LANG
lifeoff
lifeon
list
list_add
list_check
list_concat
list_del
list_disable_all
list_enable_all
list_find
list_id
list_name
list_purge
list_replace
list_save
list_search
list_set
list_str
list_zap
live
main
me
menu
menu_save
MENU_TAG_ID
menu_toggle
module_init
mouse_pos
move
movef
moveto
nameof
new
null
obj
obj_disable
obj_disable_all
obj_disabled
obj_enable
obj_enable_all
obj_look
obj_remove
objs
obj_save
obj_search
obj_str
obj_tag
obj_xref
onext
opairs
ordered_i
p
par
pclr
pget
phr
_phr
phrase
phrase_action
phrase_look
phrase_save
phrase_seen
pl
place
placef
placeto
player
player_action
player_back
player_go
player_goto
player_inv
player_look
player_moved
player_objs
player_save
player_tagall
player_take
player_use
player_ways
pn
poff
pon
ponoff
pr
prem
pseen
punseen
purge
put
putf
putto
readdir
ref
remove
replace
restore_music
rnd
room
room_look
room_save
room_scene
savemembers
save_music
savevar
seen
set_music
set_sound
set_timer
sound_channel
sound_free
sound_load
sound_panning
sounds_free
sound_volume
sprite_alpha
sprite_copy
sprite_draw
sprite_dup
sprite_fill
sprite_free
sprite_load
sprite_pixel
sprite_rotate
sprite_scale
sprites_free
sprite_size
sprite_text
sprite_text_size
stat
stead
stead_version
stop_music
stop_sound
strip
take
takef
taken
taketo
theme_var
time
timer
txtb
txtbottom
txtc
txtem
txtj
txtl
txtmiddle
txtnb
txtnm
txtr
txtst
txttab
txttop
txtu
vobj
vobj_act
vobj_save
vobj_used
vroom
vroom_enter
vroom_save
vway
ways
where
xref

В 1.4.0 также присутствуют:

global
goback
goin
goout
isVobject
path
var
variables
__vars_add
__vars_fill
vars_object
visited
visits
vobj_use

P.S. Конечно, мне бы ещё вычеркнуть пользовательский интерфейс, чтоб можно было сразу по списку скрыть объекты, но я хочу спать:) Опять же, пользователь может предварять сомнительные функции словом local, тогда они никак не затронут инстедовских внутренностей. Что характерно, вызванный с помощью dofile lua-файл не видит переменных, объявленных как local в вызывающем файле (хотя видит его глобальные). Точнее, вызываемый может оперировать глобальной для обоих одномённой переменной, но в вызывающем файле она будет перекрываться локальной версией. Этим можно воспользоваться и записать внутренние объекты stead.lua как local. Следя, чтобы в модулях было видно всё, что надо. Такие пироги. Пойду спать.

power save mode

Re: Точка _G: внутренности движка опасно лежат в глобале

спасибо за идею с local и за список. хорошо бы выделить набор функций, переопределение которых действительно вызовет проблемы в работе движка.

Т.е. из глобального списка нужно удалить api(в том числе не документированные) и те функции которые дублируются в таблице stead.

В итоге останутся внутренние функции, которые надо прятать.

На вскидку это функции: obj_xxxxx, dialog_xxxx и подобные.

Re: Точка _G: внутренности движка опасно лежат в глобале

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

Немного сократил список, будет время еще сокращу. Часть из этих функций можно спрятать без проблем.

allocator_save
call
call_bool
callpop
callpush
call_value
cctx
check_list
check_object
check_player
check_room
clearargs
clearvar
deref
dialog_empty
dialog_enter
dialog_look
dialog_phrase
dialog_poff
dialog_pon
dialog_prem
dialog_pseen
dialog_punseen
dialog_rescan
dialog_scene
do_ini
do_savegame
for_each
for_each_codeblock
for_each_list
for_each_object
for_each_player
for_each_room
for_everything
game_ini
game_life
game_load
game_save
game_start
game_step
get_autosave
get_gamepath
get_savepath
get_steadpath
get_ticks
go
goto
here
iface
ilist
inext
inherit
input
instead
instead_version
inv
isCode
isDialog
isDisabled
isEnableAutosave
isEnableSave
isFading
isForcedsc
isForSave
isList
isMenu
is_music
isObject
isPhrase
isPlayer
isRemoved
isRoom
isSceneUse
is_sound
isStatus
isVroom
isXaction
list
list_add
list_check
list_concat
list_del
list_disable_all
list_enable_all
list_find
list_id
list_name
list_purge
list_replace
list_save
list_search
list_set
list_str
list_zap
me
menu_save
MENU_TAG_ID
menu_toggle
obj_disable
obj_disable_all
obj_disabled
obj_enable
obj_enable_all
obj_look
obj_remove
objs
obj_save
obj_search
obj_str
obj_tag
obj_xref
onext
opairs
ordered_i
phrase
phrase_action
phrase_look
phrase_save
phrase_seen
player_action
player_back
player_go
player_goto
player_inv
player_look
player_moved
player_objs
player_save
player_tagall
player_take
player_use
player_ways
ref
restore_music
rnd
room_look
room_save
room_scene
savemembers
savevar
stead
strip
time
timer
txtem
txtnm
vobj
vobj_act
vobj_save
vobj_used
vroom_enter
vroom_save
ways
xref
isVobject
variables
__vars_add
__vars_fill
vars_object
vobj_use

4 (edited by wolz 2011-07-06 14:58:43)

Re: Точка _G: внутренности движка опасно лежат в глобале

Решение видится таким: все непользовательские объекты, совсем все, убираются в {} stead. Они никуда не скрываются, их можно переопределить, но в глобальном пространстве движок занимает только имя stead и имена документированных объектов. Непосредственно же в stead.lua, да и в любом месте (например, в модулях), можно определить локальные псевдонимы внутренних объектов, чтобы в пределах stead.lua обращаться к ним напрямую без префикса stead.

-- stead.lua

stead = { --[[ ... ]] };

-- была function callpush(v,...), стала
function stead.callpush(v,...)
  -- добавили префикс, остальное в оригинале
end;

-- псевдоименуем
local callpush = stead.callpush; -- ура, текст функций stead.lua,
-- использующих callpush, даже менять не надо, а остальным пофик. и т.д. 
power save mode

Re: Точка _G: внутренности движка опасно лежат в глобале

Для некоторых так и надо (напрмер cctx()). Некоторые уже в stead. Но для всех сразу не получится. Например, dialog_xxx и прочие базовые функции-обработчики, если это все поменять - улетит совместимость. А идейная чистота менее ценна, чем совместимость. На мой взгяд движение в эту сторону, конечно нужно (и оно происходит, для этого stead таблица и появилась), но постепенное и осторожное. С local хорошая идея.

Re: Точка _G: внутренности движка опасно лежат в глобале

Можно подключать разные файлы для низких instead_version

Александр Яковлев, к вашим услугам.

Re: Точка _G: внутренности движка опасно лежат в глобале

Да, но лучше осторожно и плавно переходить, начиная с очевидно безопасных для скрытия функций. Выпуск новой версии всегда дорогое удовольствие, учитывая кол-во портов.  А когда дойдем до несовместимости - тогда и ветвление поставим.

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

Re: Точка _G: внутренности движка опасно лежат в глобале

В 1.4.5 многие короткие и низкоуровневые функции перенесены в stead (например, stead.ref/deref/call/callpush/pop)
Но они также видны по старым именам (для совместимости).

Это означает, что коллизии не будут влиять на работу самого инстеда, так как внутри движок работает со stead.xxx функциями.

Перенесены пока только самые низкоуровневые вещи.