In gjs docs I found that underscore is used to denote private variables, but what does it do when creating objects with new or calling methods? For example in default code that gets generated when creating extension:
...
let item = new PopupMenu.PopupMenuItem(_('Show Notification'));
item.connect('activate', () => {
Main.notify(_('Whatʼs up, folks?'));
});
this.menu.addMenuItem(item);
...
What you see there is the _() function, which is a shorthand for gettext(). In other words, it marks a string as translatable, and will load the translated string (if available) when it's run by the user.
ie.
const store = {
values: new Map(),
// (gross trivial accessor)
setValue: action( (state, payload) => {
state.values.set(payload.key, payload.value);
}
}
I'm curious because easy-peasy uses a Proxy on the store object (and objects nested within) so that in your action you can safely mutate the state object directly (https://easy-peasy.now.sh/docs/tutorials/primary-api.html#modifying-the-state). I don't know if this also works when using non Plain Old JavaScript Objects, such as Maps.
It looks like this is possible on certain versions, but not without first declaring support for the feature (so the code above will not work right out of the box, as of now). See here for more info: https://github.com/ctrlplusb/easy-peasy/issues/440
obj.prototype.__proto__ = events.EventEmitter.prototype
I have seen the code above sometimes, and I google about it, they say this line copy all of the EventEmitter properties to the obj. And I also see the code like this:
obj.__proto__ = events.EventEmitter.prototype
So I am wondering if they are the same?
I saw the first usage in this article, in which the author gives the exapmle:
var events = require('events');
function Door(colour) {
this.colour = colour;
events.EventEmitter.call(this);
this.open = function()
{
this.emit('open');
}
}
Door.prototype.__proto__ = events.EventEmitter.prototype;
var frontDoor = new Door('brown');
frontDoor.on('open', function() {
console.log('ring ring ring');
});
frontDoor.open();
And he explains:
This line: Door.prototype.__proto__ = events.EventEmitter.prototype; Copies all of the EventEmitter properties to the Door object.
As to the second way, I saw it in the source of hexo, in the init.js, there are code:
var hexo = global.hexo = {
get base_dir(){return baseDir},
get public_dir(){return baseDir + 'public/'},
get source_dir(){return baseDir + 'source/'},
get theme_dir(){return baseDir + 'themes/' + config.theme + '/'},
get plugin_dir(){return baseDir + 'node_modules/'},
get script_dir(){return baseDir + 'scripts/'},
get scaffold_dir(){return baseDir + 'scaffolds/'},
get core_dir(){return path.dirname(dirname) + '/'},
get lib_dir(){return dirname + '/'},
get version(){return version},
get env(){return env},
get safe(){return safe},
get debug(){return debug},
get config(){return config},
get extend(){return extend},
get render(){return render},
get util(){return util},
get call(){return call},
get i18n(){return i18n.i18n},
get route(){return route},
get db(){return db}
};
hexo.cache = {};
// Inherits EventEmitter
hexo.__proto__ = EventEmitter.prototype;
// Emit "exit" event when process about to exit
process.on('exit', function(){
hexo.emit('exit');
});
The statements are not the same.
Rather than obj.prototype.__proto__ = events.EventEmitter.prototype, I'd expect to see something like Constructor.prototype.__proto__ = events.EventEmitter.prototype, (where Constructor is any kind of constructor function, so could have any name. They're often capitalized.) because the prototype property is typically only available on functions, and does not have any special meaning when defined as a property of a regular (non-function) object.
In other words, obj in first line of code given should be a (constructor) function to make sense, and it's very uncommon to see a function have such a generic variable name as obj.
If you'd share the source where you find the exact first statement, this may clear things up.
The second example is the simplest. There's no constructor involved. hexo is a plain object created with an object-literal. The author wants the EventEmitter methods to be available through the hexo method, so he assigns EventEmitter.prototype to the __proto__ property, which actually changes the prototype of hexo.
The first code example is somewhat more complex. Here the author wants to ensure that any objects that are constructed by the Door function will provide access to the EventEmitter methods. Any object constructed by the Door function will get Door.prototype as its prototype. This particular prototype now has the EventEmitter as its prototype, so the EventEmitter functions are accessible by going two steps up the prototype chain.
"Copies all of the EventEmitter properties to the Door object." - this particular comment is misleading. No properties are copied. The only that happens is this.
door = new Door
door.on("open", function() { console.log("door has opened")})
The prototype of door is now Door.prototype. If a property (in this case on) is not found when trying to access it, the JS engine will look at this prototype. The prototype of door - Door.prototype - has no on defined either, so the JS Engine will see if Door.prototype has a prototype. It does, in the form of events.EventEmitter.prototype. And this object does have an on property defined.
Hope this makes things somewhat more clear. Javascript prototypical inheritance is quite tricky.
See also Confusion about setting something.prototype.__proto__
The prototype property is generally found on constructors, that is, Functions that create new objects. The prototype of a constructor is the object that is used as the prototype for the newly instantiated object.
The __proto__ property of an object points to the object which was used as a prototype, when the object was first instantiated. It is non-standard, so there's no guarantee that your JavaScript engine will support it.
In your examples, you can see that they refer to Door.prototype and hexo.__proto__. The crucial difference here is that Door is a constructor, whereas hexo is an instance of an object.
However, Door.prototype is an instance of an object, so to get its prototype, you need to use __proto__.
In both instances, the RHS of the assignment is a constructor, so refers to prototype.
In summary, if you want the prototype that will be used by a constructor, use prototype. If you want the prototype of an instantiated object, you may be able to use __proto__.
In truth, you may better off just using Object.getPrototypeOf.
Source
Everything in JavaScript is object. And every object, it may be a function, {}, new Object(), in JavaScript has an internal property called [[Prototype]].
[[Prototype]] is the very reason for prototype inheritance in JavaScript. This internal property is exposed to the programmer through __proto__. This is a non-standard. Not all JS environments support this.
How does an object we create using constructor functions gets its [[Prototype]]?
Only objects whose [[Class]] is Function gets the property prototype. What it means is that every function declared when executed by the JS engine, it creates an object. Its [[Class]] is set to Function and a property prototype is attached to this function object.
By default this prototype is an object with one property constructor pointing to the function object.
When the above function is invoked as part of new operator like new constructorFn(), the JS engine creates an object, its [[Class]] property set to Object and [[Prototype]] property set to the object pointed to by the [[Prototype]] of the constructor function.
Since this new created object is of class Object, it does not have the prototype property.
In nutshell, __proto__ exists in every object. prototype exists, by default, only in objects whose [[Class]] is Function. What this means is only functions (created via function statement, function expression, Function constructor ) will have this property.
I have a question about declaring $helper explicitly.
This is sample code from CakePHP Book.
<?php
class PostsController extends AppController {
public $helpers = array('Html', 'Form');
..
}
In my code, I didn't have that declaration at all, but my app is still working, I can save data via my web form, I can also using $this->Html->link().
Do I really need that declaration, any disadvantages if I didn't?
Thanks to all.
The $helpers variable only needs to be declared when you are using a Helper other than 'HTML' and 'Form'. The core helpers 'Html' and 'Form' are loaded by default into the $helpers array, so the declaration is unnecessary if you only intend to use these.
If you want to add a custom helper, or use any other core helper, then you must declare the $helpers array. When you do this, you are overwriting the default helpers array, so you need to make sure to include the defaults again if you still intend to use them.
// Default. You do not need to declare this if you
// only intend to use these helpers.
$helpers = array('HTML', 'Form');
// Add 'CustomHelper' to $helpers array. In this case
// HTML and Form must be declared.
$helpers = array('HTML', 'Form', 'Custom');
I am currently using CSS to change everything I write to upperCase when I create an entry, but that is not enough. When I save things, the text shown in the text fields is upper case, but the real value that Grails stores stays in lower case.
I am assuming I'd need to change something in the controller or anything.
Maybe transforming the $fieldValue CSS could work??
Any ideas would help!
Thnks!
You could just write setters for your domain object?
class Domain {
String aField
void setAField( String s ){
aField = s?.toUpperCase()
}
}
I think you are asking how to change values on your domain objects to uppercase. If this is not the case please clarify the question.
You have a bunch of options. I would recommend
1) In a service method, before you save, using String.toUpperCase() to modify the appropriate values on the domain object.
or
2) You can use the underlying Hibernate interceptors by defining a beforeInsert method on your domain object, and doing the toUpperCase there. (see 5.5.1 of the grails documentation)
or
3) You could do this client side. However, if it is a "business requirement" that the values are stored as upper, then I recommend doing the translation server side. It is easier to wrap tests around that code....
Using annotations is cleanest approach
import org.grails.databinding.BindingFormat
class Person {
#BindingFormat('UPPERCASE')
String someUpperCaseString
#BindingFormat('LOWERCASE')
String someLowerCaseString
}
Here is link for it: Grails doc for data binding
You can use Groovy metaprogramming to change the setter for all domain class String-typed properties without actually writing a custom setter for each property.
To do this, add something like the following to the init closure of Bootstrap.groovy
def init = { servletContext ->
for (dc in grailsApplication.domainClasses) {
dc.class.metaClass.setProperty = { String name, value ->
def metaProperty = delegate.class.metaClass.getMetaProperty(name)
if (metaProperty) {
// change the property value to uppercase if it's a String property
if (value && metaProperty.type == String) {
value = value.toUpperCase()
}
metaProperty.setProperty(delegate, value)
} else {
throw new MissingPropertyException(name, delegate.class)
}
}
}
}