I am implementing an API in Rails 3, and noticed an example controller defined like class Api::ToursController < ApplicationController. Does anyone know what the to colons indicate? Is it inheritance? Or is it indicating extending the ToursController? I have tried searching for an answer, but have not come up with anything.
Here is what I am referencing: https://github.com/nesquena/rabl/wiki/Set-up-rabl-for-Ruby-on-Rails
:: is the scope resolution operator (i.e. namespace operator) in many languages, including C++ and Ruby, so it's not specific to Rails.
In Ruby, modules define namespaces, so you can see code like this:
Net::HTTP.get 'stackoverflow.com'
Which calls the get class method on the HTTP class in the Net module.
In Rails, namespaces allow you to better organize your code (e.g. to separate your API controllers from the rest), and are implemented as modules.
Api::ToursController indicates that there is an outer Module called Api , in which the ToursController class is located. :: is the namespace operator.
Sometimes you see a module name preceded with :: , e.g. ::Something , this indicates to Ruby to look in the outer-most namespace (Main) for the Class or Module called Something. This typically happens when you're somewhere in the source code of a gem and it references an outer Class or Module.
You can do include Api to include everything in the Module Api at the current level, this way you don't need the namespace operator, and can use ToursController without prefixing it with 'Api::'
It's namespace! Module::Class.method
Related
I am trying to implement a custom control (I call it DataGrid) , which I choose to derive from Selector. In cppwinrt , I write some like this
struct DataGrid : SelectorT<DataGrid>
{
}
This code does not compile. In fact , there is no such a struct called SelectorT in any of the shipped Windows.UI.Xaml.Controls.Primitives.h files. I've checked the winmd file shipped with the SDK (19041) , found that Selector is Composable (has the ComposableAttribute attribute), so, SelectorT should have been generated , what I've missed ? Many thanks!
There is no SelectorT because Selector can not be subclassed. The TypenameT class templates in the consuming projection are not provided for convenience, they exist to provide user-defined subclasses of Xaml types that support it. This allows the user to define their own implementations of overrideable methods. (Think of it as similar to C++ virtual functions, but in a complicated COM aggregation way)
The docs don't appear to spell out in clear words which classes can be subclassed, and which ones can't. You can deduce this, though, from the presence of ComposableAttribute on the type, as in FrameworkElement.
In our project I recently dumped a list of routes to controllers in order to learn a new asp.net project that I recently joined the team of.
However, they have a class used as an attribute in a namespace that is being picked up by asp.net as a controller class, which is registering 'null' / empty routes in the dump, named GenericController.
Is there a way to mark this class using attributes (Similar to marking methods using [NonAction]) as 'not a controller?' And if not, what alternatives are there for excluding 'matching by convention' named classes from being controllers?
Is there a way to mark this class using attributes (Similar to marking methods using [NonAction]) as 'not a controller?'
There's a built-in [NonControllerAttribute].
Also, you can make your class a nested class, an abstract class, an internal class, a generic class , etc to avoid picking it as a Controller.
Fore more details, see Source Code
The official site of Typescript get me ask a question,
"Do we need to use namespace or not?".
The following quote explains the 2 things well:
It’s important to note that in TypeScript 1.5, the nomenclature has
changed. “Internal modules” are now “namespaces”. “External modules”
are now simply “modules”, as to align with ECMAScript 2015’s
terminology, (namely that module X { is equivalent to the
now-preferred namespace X {).
So, they suggest that TS team prefer namespace.
Further, it says we should use "namespace" to struct the internal module:
This post outlines the various ways to organize your code using
namespaces (previously “internal modules”) in TypeScript. As we
alluded in our note about terminology, “internal modules” are now
referred to as “namespaces”. Additionally, anywhere the module keyword
was used when declaring an internal module, the namespace keyword can
and should be used instead. This avoids confusing new users by
overloading them with similarly named terms.
The above quote is all from the Namespace section, and yes, it says again, but in a internal secnario.
but in the module section, one paragraph, says that:
Starting with ECMAScript 2015, modules are native part of the
language, and should be supported by all compliant engine
implementations. Thus, for new projects modules would be the
recommended code organization mechanism.
Does it mean that I don't need to bother with namespace, use module all along is the suggested way to develop?
Does it mean that I don't need to bother with namespace, use module all along is the suggested way to develop?
I wouldn't put it exactly that way... here's another paraphrase of what has happened. One upon a time, there were two terms used in Typescript
"external modules" - this was the TS analog to what the JS community called AMD (e.g. RequireJS) or CommonJS (e.g. NodeJS) modules. This was optional, for some people who write browser-based code only, they don't always bother with this, especially if they use globals to communicate across files.
"internal modules" - this is a hierarchical way of organising your variables/functions so that not everything is global. The same pattern exists in JS, it's when people organise their variables into objects/nested objects rather than having them all global.
Along came Ecmascript 2015 (a.k.a. ES6), which added a new formal, standard format that belonged in the "external modules" category. Because of this change, Typescript wanted to change the terminology to match the new Javascript standard (being that it likes to be a superset of Javascript, and tries its best to avoid confusion for users coming from Javascript). Thus, the switch of "external modules" being simplified to just "modules", and "internal modules" being renamed to "namespaces".
The quote you found here:
Starting with ECMAScript 2015, modules are native part of the language, and should be supported by all compliant engine implementations. Thus, for new projects modules would be the recommended code organization mechanism.
Is likely alluding to guidance for users who were not yet using (external) modules. To at least consider using it now. However, support for ES6 modules is still incomplete in that browsers as of May 2016 don't have built-in module loaders. So, you either have to add a polyfill (which handles it at runtime) like RequireJS or SystemJS, or a bundler (like browserify or webpack) that handles it at build time (before you deploy to your website).
So, would you ever use both modules (formerly "external modules") and namespaces? Absolutely - I use them both frequently in my codebases. I use (external) modules to organise my code files.
Namespaces in Typescript are extremely useful. Specifically, I use namespace declaration merging as a typesafe way to add extra properties to function objects themselves (a pattern often used in JS). In addition, while namespaces are a lot like regular object variables, you can hang subtypes (nested interfaces, classes, enums, etc.) off of their names.
Here is an example of a function with a property (very common in NodeJS libs):
function someUsefulFunction() {
// asynchronous version
return ...; // some promise
}
namespace someUsefulFunction {
export function sync() {
// synchronous version
}
}
This allows for consumers to do this common NodeJS pattern:
// asynchronous consumer
someUsefulFunction()
.then(() => {
// ...
});
// synchronous consumer
someUsefulFunction.sync();
Similarly, say you have an API that takes in an options object. If that options type is specific to that API,
function myFunc(options?: myFunc.Options) {
// ...
}
namespace myFunc {
export interface Options {
opt1?: number;
opt2?: boolean;
opt3?: string;
}
}
In that case, you don't have to pollute a larger namespace (say whole module scope) with the type declaration for the options.
Hope this helps!
I've used typescript from some months now and i have not understand the difference from namespaces and modules yet.
I know that before they were named internal and external modules, but with both i can import classes from other files. So what is the real difference?
As it is stated in the TS-handbook
there are 2 kind of modules: "internal" & "external". The code in the internal module is written in Typescript and the "external" is written in Javascript.
In order to align with new ECMAScript 2015's terminology they decided to rename them as follows:
"Internal modules" are now "namespaces".
"External modules" are now simply "modules", as to align with ECMAScript
So:
The way you write your code is different
When using modules the classes are not exposed in the global scope, while using namespaces:
Example:
Let's say you have public namespace sequence NamespaceA.NamespaceB.NamespaceC which exposes public class ClassD.
You can access all of these globally this way:
window.NamespaceA
window.NamespaceA.NamespaceB
window.NamespaceA.NamespaceB.NamespaceC
window.NamespaceA.NamespaceB.NamespaceC.ClassD
without saying window.NamespaceA = NamespaceA
and if you use modules you have to use the "magic" above
Namespaces are TypeScript's way of structuring code when you don't want the outputed Javascript code to use a module loader.
You can find more about namespaces vs modules in the handbook here.
[This is a follow-up question to "How I can modularize Rails model?"]
Is there anyway to organize classes in app/models directory of Rails?
Do I have to use single top-level namespace for all of the classes?
Initial motivation is, I want place business logic classes which do not inherited from ActiveRecord::Base into app/models directory. Searching this site reveals many answers which recommend to place business logics classes in the app/models directory. I posted a different question, and got recommendation that it is possible to place such classes into lib directory.
Now I'm curious. I'd like to place these classes into different namespace and directory in apps/models directory which recommended by others. Is it possible?
Actually, I experiment that, but it seems to me that is what rails is not expected. If I create such a class (like SomeModName::ClassInMod in some_mod_name/class_in_mod.rb ) it does not get loaded. Also, I defined constants inside the module. Since they're not loaded, I can't use them. Actually, with rspec it work without problem, but with rails server, the class does not loaded. I'm sure it is related to autoloading issue.
In addition to the classes mentioned above, classes inherited from ActiveRecord::Base can be placed into some namespaces inside a module. I'm curious whether this work well or not too.
So the question in other words: can I make rails happy by configuring these files to be loaded, or is not the way rails designed?
Yes, you can define an ActiveRecord class in a module. The easy way is to use the generator:
./script/rails generate model logic/phase_logic
./script/rails generate model logic/evaluation_logic
Observe, that Rails will create additionally a file with the definition of the module. In this case:
# app/models/logic.rb
module Logic
...
end
# app/models/logic/phase_logics.rb
class Logic::PhaseLogic < ActiveRecord::Base
...
end
# app/models/logic/evaluation_logics.rb
class Logic::EvaluationLogic < ActiveRecord::Base
...
end
Your problems with constants defined in the module were caused by the fact, that you defined the constants in the definition module "wrapped" around only one model, from the two you have created. A very important part in understanding ruby (and Rails) - especially for people who have strong background in compiled languages - is to remember that there is no compilation phase, so the definition of some class is read and executed only when that specific class is used. Sometimes a week after the application server has been started and served thousands of requests.
Thus, as I said in the previous question's answer, the problem with autoloading was that sometimes the definition of the constants was read after the definition which was trying to use them. The order was random - if the first used object happened to be EvaluationLogic, then the error emerged. It the first object happened to be PhaseLogic, everything was fine.
Now, when you have a file for the module itself, and define constants in that file (app/models/logic.rb), autoloading will be able to find and execute the definitions before any class starts to use them. I hope everything will be OK.