From: shevegen@... Date: 2018-05-15T09:03:11+00:00 Subject: [ruby-core:87039] [Ruby trunk Feature#14758] Add a first-class support for isolated bounded packages / modules / contexts Issue #14758 has been updated by shevegen (Robert A. Heiler). I am mostly neutral to somewhat against it; not because of the additional information, but because of the **restrictions** put on ruby hackers. I think Daniel already summed some part of it up via: > Also I only test the API. > I don't unit test internal modules or classes. Which I think makes sense. The internal part should not be relevant, neither for testing, nor anyone else to access it (why would anyone access internals? Did you provide means aka an API to access the **functionality**? Because if you did not, then you could do so - and if you did, I don't understand why anyone would WANT to access the internals, anyway?) The part of the proposal here, though: MyModule::MyIsolatedClass # raises context violation goes against ruby's philosophy in my opinion since you attempt to restrict what people can do. Ruby still has .send() which I love; .public_send() was added but .send() remains as-is and I am pretty sure that .send() will always be there - it's sort of the smalltalk influence on ruby here. Why would you want to prevent others from accessing any part of ruby code? Is it a real problem? Does something break if others do? In all the explanations given, I have never read an explanation as to WHY it should be restricted exactly. You can always document for people to not do so, and instead provide common API entry points. What I do is to usually define top-level module-methods, such as: module Foobar # code here And then call it like: Foobar.do_this_or_that where internally classes can be called through these methods. I also do this in large projects, at the least for the more important classes. And these usually are callable from the commandline via "--options" like: foobar --clean-up-directories foobar --clean-directories foobar --cdirs like aliases. Also note that ruby's core philosophy is to let people (ruby hackers) do what they want to. That is one reason why there is no strict separation between public/private, and why we always had .send(), which is similar to smalltalk. Python does not have a strong public/private distinction either by the way. All these proposals ultimately always try to restrict what ruby hackers can do, for no good reason. I am not against providing additional cues, mind you - for example, I'd like to have a way to specify extra information to denote on the toplevel "namespaces", so that we can distinguish whether something is "owned" by ruby core (like top-level Kernel), as opposed to other modules. From this context I'd also like to redefine refinements (the proposal for them), but it's a bit complicated and not trivial to write a good proposal for change. It's much easier to make smaller changes than large ones. Also in the linked issue: ::Foo::Bar.new.baz => error: internal method being called outside ::Foo namespace To me, it goes against the old ruby philosophy. But I think it is not really good to comment against it because, either way, it will be matz who decides, and you only have to convince matz, not me nor anyone else. And he once said that you can persuade him with arguments but keep in mind that others also feel strongly about losing flexibility that they used to have. :) ---------------------------------------- Feature #14758: Add a first-class support for isolated bounded packages / modules / contexts https://bugs.ruby-lang.org/issues/14758#change-72004 * Author: grzesiek (Grzegorz Bizon) * Status: Open * Priority: Normal * Assignee: * Target version: ---------------------------------------- While one of the core principles of Ruby is to extend the language in a way it is a most useful and convenient tool that a software developer can have in their toolbox, lack of a first-class isolation on module level can cause some serious problems when project grows beyond some size. This is especially visible in large projects, where most of the code lives in the `lib/` directory, and there are tens or hundreds of modules there. Ideally we would like to make these modules isolated and hide complexity behind facades. Currently it is not possible to isolate such modules, because a developer can still reach beyond boundary of a bounded context, and use `MyModule::InternalClass` directly. It is very difficult to enforce boundaries, currently it requires a lot of work to implement complex static analysis rules. Would it make sense to add support for first-class `package`, `context` or `boundary`, that would be a regular module but would not allow referencing inner constants from outside? ~~~ context MyModule class MyIsolatedClass # ... end def self.build MyIsolatedClass.new end end MyModule::MyIsolatedClass # raises context violation MyModule.build # => Returns an instance of MyModule::MyIsolatedClass ~~~ I'm pretty sure that I failed at finding similar feature proposal that has been already submitted, in that case sorry for that! Please let me know what do you think about that! Thanks in advance! <3 -- https://bugs.ruby-lang.org/ Unsubscribe: