"String"테이블을 "확장" - 어떻게해야합니까? 좋은 생각조차?
-
19-09-2019 - |
문제
나는 주어진 문자열의 첫 글자를 대문자로 해야하는 LUA 라이브러리를 개발하고 있습니다. 따라서 다음 기능을 만들었습니다.
local capitalize = function(s)
return string.gsub (s,
"(%w)([%w]*)",
function (first, rest)
return string.upper(first) .. rest
end,
1 )
end
이것은 처음에 내 라이브러리에서만 사용되는 "내부"기능이었습니다.
이제 사용자가 경우에 따라이 기능을 사용하고 싶다는 것을 깨달았습니다.
질문 1스트링 테이블을 확장 할 생각이지만 진행 방법에 대해 확신이 없습니다. 이것을하기에 충분합니까, 아니면 더 "루아 지향적"방법이 있습니까?
string.capitalize = function(s)
... etc etc (same code as above)
질문 2MonkeYpatch 문자열에 좋은 생각 조차지 궁금합니다. 대신 공개 "자본화"기능을 제공해야합니까?
편집 - 누구나 미래에 이것을 찾을 경우, 훨씬 간단한 "Capitalize"기능이 문자열 레시피 페이지:
str = str:gsub("^%l", string.upper)
해결책
나는 자주 내장 테이블을 확장시킨다. 나는 주로 중요한 것이 실제로 빠졌다고 생각할 때 이것을한다. 자본화는 내 "중요한"목록을 만들지 않았지만 string.split
예를 들어.
이렇게하면 프로그래밍 컨벤션을 따릅니다.
require 'stringutil' -- load extra stuff into string.*
require 'osutil' -- load extra stuff into os.*
당신은 아이디어를 얻습니다.
내가 조심할 때 내가하는 또 다른 일은 아직 존재하지 않는 것을 덮어 쓰지 않도록하는 것입니다.
function extend(tab, field, val)
if tab[field] == nil then
tab[field] = val
return val
elseif tab[field] ~= val then
error(string.format('Extension %s.%s failed: already occupied by %s',
nameof(tab), field, tostring(val)))
else
return val
end
end
그만큼 nameof
기능은 다음과 같습니다.
function nameof(val)
for name, v in pairs(_G) do if v == val then return name end end
return '?'
end
최종 참고 : 다른 사람과 코드를 공유하려고 할 때 사전 정의 된 테이블을 수정하지 않는 경향이 있습니다. 황금 규칙에 따르면, 그 네임 스페이스는 모든 사람이 공유하고 있으며, 다른 사람들이 내 코드를 사용하는 경우, 사전 정의 된 분야에서 원하는 필드를 잡는 것만으로도 공평하지 않습니다. string
테이블.
다른 팁
질문 1에 대한 답은 "예"입니다. 질문 2에 대한 답은 "맛의 문제"입니다.