lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On 13 June 2016 at 05:44, Pierre Chapuis <catwell@archlinux.us> wrote:
> June 10 2016 10:39 PM, "Hisham" <h@hisham.hm> wrote:
>
>
>> My reasoning for the latter is that using inconsistent, `local x =
>> require "y"` types of names is counterproductive: especially when
>> looking at someone else's code, having to keep in mind how a module
>> author decided to call a well-known library is an avoidable extra
>> cognitive load, and having to skim back and forth to look at the
>> require() list is annoying.
>>
>> [...]
>>
>> So, in short, the way I try to do things is to keep it simple:
>>
>> project Foo, rockspec foo, local foo = require("foo")
>
>
> I think it depends what kind of code you are writing,
> and which dependency you are talking about.
>
> First, you cannot always do that. For instance, even
> ignoring the pl / penlight distinction, you probably
> never want to require "pl" in a large project. So you
> do things like:
>
>     local pretty = require "pl.pretty".
>
> Second, the local variable you are going to use is
> an abstraction whereas the module is an implementation.
> It makes a lot of sense to write something like:
>
>     local json = require "cjson"
>
> because json and cjson can (in most cases) be used
> interchangeably.
>
> Third, for modules that behave like classes but I need
> a singleton, I often want to keep the name for the
> singleton, i.e.:
>
>     local Redis = require "redis"
>     local redis = Redis.new(...)

Agreed on all points. As I said, the simplest solution is something I
aim at, but not something that can be done 100% of the time. (I view
`local pretty = require "pl.pretty"` as an extension of the idea for
namespaced modules; I do the same in the LuaRocks codebase). As for
the Redis example, I have mixed feelings as for which is the best
solution; either the one you posted or, if Redis isn't used anywhere
else,

     local redis = require("redis").new(...)

I've struggled with this in a recent project, and haven't come to an
ideal solution (I danced around the issue loading the class with
`local foo = require("bla.foo")` and then initializing the instance
inside another table with `self.foo = foo.new()`). In a sense I feel
like the 'right' thing to do would be to name the module Foo in
uppercase, but I feel it's not practical because of case-insensitive
filesystems...

> Finally, I am starting to like the practice of module
> namespacing by organization, i.e. "mycompany.util.stack".
> However when doing this I am unsure how to package those
> modules as rocks. Make a single "mycompany" rock?
> Make "mycompany-util"? Make "mycompany-util-stack"?

I think there's no hard rule, but checking the dependencies serves as
a good heuristic. If mycompany-util-stack is usable without pulling
lots of the other mycompany-util code, then it could be a stand-alone
rock; OTOH if people loading mycompany-util-stack will end up
indirectly pulling 80% of the mycompany-util namespace anyway, then
maybe it's just simpler to pack it all as one rock. Recently I
separated a project in four different rocks because of the
dependencies the components themselves pulled, so that reusable and
platform-specific parts were nicely isolated.

-- Hisham