use lazy generation instead of metaclass