From 75b5fd054a505631ebcdfe580c58bd868d80c515 Mon Sep 17 00:00:00 2001 From: Vladimir Davydov <vdavydov@tarantool.org> Date: Tue, 1 Aug 2023 13:38:29 +0300 Subject: [PATCH] compat: move is_new and is_old option methods to metatable The is_new and is_old methods are the same for all compat options so they should be defined in a metatable. A good thing about this change is that it removes is_new and is_old from serialization: * Before: NO_WRAP tarantool> require('compat').yaml_pretty_multiline --- - is_new: 'function: 0x4175d6e8' is_old: 'function: 0x4175d790' brief: | Whether to encode in block scalar style all multiline strings or ones containing "\n\n" substring. The new behavior makes all multiline string output as single text block which is handier for the reader, but may be incompatible with some existing applications that rely on the old style. https://tarantool.io/compat/yaml_pretty_multiline current: default default: new ... NO_WRAP * After: NO_WRAP tarantool> require('compat').yaml_pretty_multiline --- - current: default brief: | Whether to encode in block scalar style all multiline strings or ones containing "\n\n" substring. The new behavior makes all multiline string output as single text block which is handier for the reader, but may be incompatible with some existing applications that rely on the old style. https://tarantool.io/compat/yaml_pretty_multiline default: new ... NO_WRAP To achieve that, we have to remove the option name from the usage error message but it seems to be okay because such errors shouldn't happen in practice and the error message is clear enough to figure out what went wrong. Follow-up #8807 NO_DOC=refactoring NO_CHANGELOG=refactoring --- src/lua/compat.lua | 55 +++++++++++-------- .../gh_7000_compat_module_test.lua | 11 ++-- 2 files changed, 38 insertions(+), 28 deletions(-) diff --git a/src/lua/compat.lua b/src/lua/compat.lua index aaf2116395..9c0b898dc6 100644 --- a/src/lua/compat.lua +++ b/src/lua/compat.lua @@ -428,6 +428,37 @@ function compat_mt.__newindex(_, key, val) set_option(key, val) end +local compat_option_methods = {} + +-- Returns the effective compat option value - 'old' or 'new'. +local function option_value(option) + if option.current == 'default' then + return option.default + else + return option.current + end +end + +-- Whether the effective value of the option is `new`. +function compat_option_methods.is_new(option) + if type(option) ~= 'table' then + error('usage: compat.<option_name>:is_new()') + end + return option_value(option) == 'new' +end + +-- Whether the effective value of the option is `old`. +function compat_option_methods.is_old(option) + if type(option) ~= 'table' then + error('usage: compat.<option_name>:is_old()') + end + return option_value(option) == 'old' +end + +local compat_option_mt = { + __index = compat_option_methods, +} + function compat_mt.__index(_, key) if not options[key] then error(('Invalid option %s'):format(key)) @@ -446,29 +477,7 @@ function compat_mt.__index(_, key) result.current = 'old' end - -- Whether the effective value of the option is `new`. - function result.is_new(option) - if type(option) ~= 'table' then - error(('usage: compat.%s:is_new()'):format(key)) - end - if option.current == 'new' then - return true - end - if option.current == 'old' then - return false - end - return option.default == 'new' - end - - -- Whether the effective value of the option is `old`. - function result.is_old(option) - if type(option) ~= 'table' then - error(('usage: compat.%s:is_old()'):format(key)) - end - return not option:is_new() - end - - return result + return setmetatable(result, compat_option_mt) end compat_mt.__serialize = serialize_compat diff --git a/test/app-luatest/gh_7000_compat_module_test.lua b/test/app-luatest/gh_7000_compat_module_test.lua index 39ab3c5ed7..b90ae19f38 100644 --- a/test/app-luatest/gh_7000_compat_module_test.lua +++ b/test/app-luatest/gh_7000_compat_module_test.lua @@ -234,11 +234,12 @@ g.test_is_new_is_old = function() t.assert_equals(compat[name]:is_new(), is_new) t.assert_equals(compat[name]:is_old(), not is_new) - local err_pattern = 'usage: compat.%s:%s' - t.assert_error_msg_contains(err_pattern:format(name, 'is_new'), - compat[name].is_new, nil) - t.assert_error_msg_contains(err_pattern:format(name, 'is_old'), - compat[name].is_old, nil) + t.assert_error_msg_content_equals( + 'usage: compat.<option_name>:is_new()', + compat[name].is_new) + t.assert_error_msg_content_equals( + 'usage: compat.<option_name>:is_old()', + compat[name].is_old) end end -- GitLab