What Purpose Can Anonymous Modules Serve

What purpose can anonymous modules serve?

There is a more general principle at work here.

Phil Karlton famously said: "There are only two hard problems computer science: cache invalidation and naming things." So, naming things is hard. Which means that if we can get away with not naming a thing, we should do it!

Or, if you look at it from a different perspective: if naming things is hard, then giving something a name means that thing is important. But sometimes, there are things in our programs which aren't important and thus aren't worthy of a name.

This is not unique to Ruby modules. You could ask the question about any anonymous concept, and in fact, the question does get asked all the time. When C# 2.0 introduced anonymous methods, people asked why one would ever want to use a method without a name, when C# 3.0 introduced anonymous lambdas (and anonymous types), people asked why one would ever want to use them. Python's anonymous functions are severely restricted compared to Python's named functions, and the Python community asks why one would ever need full-blown anonymous functions. Of course, we, as Ruby programmers are so used to lightweight (blocks) and fully reified (Procs) anonymous functions that we can't understand why one would ever not want to use one.

Java has anonymous classes since 1.1 and anonymous lambdas since 8. Basically, anonymous "things" are everywhere and they are useful, especially for quick one-off usage.

For example, if you just want to wrap some existing method, without going through the hassle of alias_method (which you really shouldn't use any more for that problem, Module#prepend now exists and is a much better solution), you could do:

class Array
prepend(Module.new do
def [](*)
puts 'Before-hook'
super.tap { puts 'After-hook' }
end
end)
end

p [42][0]
# Before-hook
# After-hook
# => 42

Purpose of anonymous modules in Agda

Anonymous modules can be used to simplify a group of definitions which share some arguments. Example:

open import Data.Empty
open import Data.Nat

<⇒¬≥ : ∀ {n m} → n < m → n ≥ m → ⊥
<⇒¬≥ = {!!}

<⇒> : ∀ {n m} → n < m → m > n
<⇒> = {!!}

module _ {n m} (p : n < m) where

<⇒¬≥′ : n ≥ m → ⊥
<⇒¬≥′ = {!!}

<⇒>′ : m > n
<⇒>′ = {!!}

Afaik this is the only use of anonymous modules. When the module _ scope is closed, you can't refer to the module anymore, but you can refer to its definitions as if they hadn't been defined in a module at all (but with extra arguments instead).

Why are self-executing anonymous functions used in Javascript Module pattern?

How can a self-executing function hide private variables and only expose the returned object. Why does this not happen with a normal JavaScript function?

It does happen with normal JavaScript functions.

function MakeModule() {
var privateVariable = "foo",
privateMethod = function () {
alert('private method');
};

return {
PublicMethod: function () {
alert(privateVariable);
privateMethod();
}
};
}

var Module = MakeModule();

would work just fine.

The only difference is that the anonymous function introduces one less global variable and allows for itself to be garbage collected while MakeModule can't be collected unless explicitly deleted by the author.

Modules that use an anonymous define() call must be loaded with a require() call

Anonymous define

Calling sap.ui.define([...],...) defines a module anonymously because the 1st argument is not a string (module name) but a list of the module's dependencies. If the module name is omitted, the framework automatically determines it based on how the module script was referenced.

  • Use anonymous sap.ui.define once at top-level of the JS file content, not multiple times.
  • Replace sap.ui.define with sap.ui.require when simply requiring existing modules.

Cf. my comment at https://github.com/SAP/openui5/issues/2203#issuecomment-420918457.

Named module define

The 1st argument in sap.ui.define("MyModule",[...] ,...) defines the name of the module manually which must be passed when:

  • Defining a nested module within an existing module definition in a single JS file content.
  • Defining a module which was initiated by a <script> tag from HTML.

The walkthrough is fixed with SAP/openui5@6302b8f and SAP/openui5-docs#43 accordingly.

How to get the handle of an anonymous module with requirejs?

You've misunderstood what it means to call define without a module name as the first parameter. The only thing it does is let RequireJS figure out the module name at run time on the basis RequireJS's configuration. For instance, let's suppose I have a file which from the baseUrl directory would have the relative path foo/bar.js and this file calls define without setting a module name. I could load this module by doing require(['foo/bar'], ... However, if I have the following configuration:

paths: {
bar: 'foo/bar'
}

Then I could load it with require(['bar'], ... If I had a define in the file that also sets the module name, either one of two methods of loading the module would certainly fail. If I have define('foo/bar', ... then the first require would work but not the second. If I have define('bar', ... then the second require would work but not the first.

Ultimately, though, when you load a module that does not call define with a module name, you still have to load it using some name. So you need to figure out what name the application you are examining uses to refer to the module that interests you, and use that name.

The only things you can fiddle with once a module is loaded are the values that your module export. Anything not exported is off-limits.

Once you've got a name for your module, you have to issue a require call at the console to get a reference to the module. If the module is already loaded, you can use var foo = require(module_name). This is the synchronous form of require which is convenient to use but works only if a module is already loaded. If the module is not already loaded, then you have to use something like require([module_name], function (foo_) { foo = foo_ }); (note how the first parameter is an array here) to get a global foo to be set to your module. See this answer for a more verbose expalanation.

Why are anonymous functions used?

The point of anonymous functions is that you use them only once instead of having to define them somewhere else (for reuse). It is neat because they are right where they are to be used (in a certain context).

It is your choice to use them. If you don't like them.. don't!

Mismatched anonymous define() module

Like AlienWebguy said, per the docs, require.js can blow up if

  • You have an anonymous define ("modules that call define() with no string ID") in its own script tag (I assume actually they mean anywhere in global scope)
  • You have modules that have conflicting names
  • You use loader plugins or anonymous modules but don't use require.js's optimizer to bundle them

I had this problem while including bundles built with browserify alongside require.js modules. The solution was to either:

A. load the non-require.js standalone bundles in script tags before require.js is loaded, or

B. load them using require.js (instead of a script tag)

Javascript Module Pattern with anonymous functions

It seems like you need to understand how return works in functions in order to understand why the provided examples behave the way they do.

Example 1: You create a new variable pub and adding two methods to it: add and sub. At the end, you're returning the pub variable to CalcModule

So when you call CalcModule, it returns the following object with two methods:

CalcModule = {
add: function() {...},
sub: function() {...}
}

Example 2: Let's rewrite example 2 similar to example 1...

var testModule = (function () {

var counter = 0;
var pub;

pub.incrementCounter: function () {
return counter++;
}

pub.resetCounter: function () {
console.log( "counter value prior to reset: " + counter );
counter = 0;
}

return pub;
})();

We know pub is an object...

pub = {
incrementCounter: function() { ... },
resetCounter: function() { ... }
}

and we're returning pub to testModule... therefore...

testModule = {
incrementCounter: function() {...},
resetCounter: function() {...}
}

Hope this is helpful.

Elixir: Is there any benefit of using & operator to get an anonymous function out of a named function

It's pretty common to have some simple functions like

Enum.map(list, fn(element) -> element.id end)

Or just

Enum.map(list, &(&1.id))

With some practice, second one is even easier to read than the first

Regarding your question, you can also call a named function in the same way

Enum.map(list, &Integer.to_string/1)

Alternative is to pass a function to the Enum using fn

Enum.map(list, fn(number) -> Integer.to_string(number) end)

Also, captured variant is easier to read.



Related Topics



Leave a reply



Submit