Why does intl.Message need to be wrapped in an enclosing function? - dart

Here the a suggested pattern for using Intl.message I have seen everywhere:
final String learnMoreLabel = _learnMoreLabel; String get
_learnMoreLabel => Intl.message('Learn more',
name: 'HelpContentBase__learnMoreLabel',
desc: 'The label for a link or button which takes the user to the '
'Google Help Center to read more information on a topic.');
Why can't I just write:
final String learnMoreLabel = Intl.message('Learn more',
name: 'HelpContentBase__learnMoreLabel',
desc: 'The label for a link or button which takes the user to the '
'Google Help Center to read more information on a topic.');
Why does it need to be wrapped in the getter? I found this in the docs:
Use this for a message that will be translated for different locales.
The expected usage is that this is inside an enclosing function that
only returns the value of this call and provides a scope for the
variables that will be substituted in the message.
but it doesn't say why.

The short answer is that for that example it probably could be written that way, but it breaks down when there are parameters to the message.
What happens with Intl messages is that the a preprocessor runs over the program and finds all the occurrences of Intl.message and writes them to a file. That file gets sent for translation, and then the translations are run through another program and generate Dart code for each language, which is reachable via the messages_all.dart import.
When you call Intl.message at runtime it looks up the current locale (using the name as a key) and delegates to the appropriate translation, passing along any parameters (via the "args" argument).
When the comment says "provides a scope" it really means that the only things that are allowed to be used in the message are the variables that are provided as arguments to the enclosing function. When there aren't any arguments we could allow the enclosing function to be omitted. It would mean making the parser smart enough to recognize that pattern as well.
As an aside: I don't love the pattern of calling the method once and assigning to a final variable. It sets up a potential race condition between locale initialization and variable initialization and it means the locale can't change at runtime. However, I understand when we have frameworks like Angular that are calling it and comparing the result on every frame that it gets expensive to actually call the function every time.
Another aside: When there are no parameters you can omit the name. It will use the text as a name. When there are parameters the text is an interpolation so it can't use that as the name.

Related

Why does ActionView's "select_tag" escape the HTML in its "options" argument when called directly?

So I've been going through the very poor documentation that exists for ActionView, particularly a method called select_tag that just exists when called from view files. Supposedly, it's called like this:
select_tag name, option_tags, options
The documentation says nothing at all about the name, very little about the options, and describes the option_tags only through examples that treat it as an opaque value that must be obtained from other functions.
As always, the only way to learn anything about Rails is to reverse-engineer it.
So I tried running it directly from a Rails console, which is tricky because Ruby doesn't let you call methods that are defined in modules unless you create a class and an object first:
class H
include ActionView::Helpers::FormOptionsHelper
include ActionView::Helpers::FormTagHelper
end
H.new.options_for_select ["foo","bar"]
The above usage of options_for_select comes from actual code that somebody else wrote. The return value is a string:
"<option value=\"foo\">foo</option>\n<option value=\"bar\">bar</option>"
So apparently, you're supposed to pass the return value from option_for_select (or one of the many other related functions that introduce complications I don't want to talk about such as generating HTML tags from ActiveRecord objects) as the option_tag parameter of select_tag. Except if you copy that string to your clipboard and paste it directly into a function call, it doesn't do what you'd expect:
H.new.select_tag :my_name, "<option value=\"foo\">foo</option>\n<option value=\"bar\">bar</option>"
Return value:
"<select name=\"my_name\" id=\"my_name\"><option value="foo">foo</option>\n<option value="bar">bar</option></select>"
At least this reveals what the name parameter is for.
Even weirder, the text is not escaped if you pass the return value directly to select_tag without letting it print on the console:
H.new.select_tag :name, H.new.options_for_select(["foo","bar"])
Return value:
"<select name=\"name\" id=\"name\"><option value=\"foo\">foo</option>\n<option value=\"bar\">bar</option></select>"
WTF is going on here?
In the course of writing this question, I stumbled on its answer: Ruby has been lying to me (like it always does).
When you evaluate:
H.new.options_for_select ["foo","bar"]
Ruby tells you that the result was a String. But that's only because Pry and Irb both silently call .to_s on everything, and the thing that gets returned from options_for_select has a to_s. The truth:
(H.new.options_for_select ["foo","bar"]).class
=> ActiveSupport::SafeBuffer
ActiveSupport::SafeBuffer.new("<foo>")
=> "<foo>"
So whoever wrote these methods assumed that you want to incorporate raw, user-provided strings into your <select> tags, and those strings could contain attempts at HTML/JavaScript injection, so they must be escaped.
ActiveView treats all strings as suspect, but it is possible to mark certain strings as "safe" by wrapping them in an ActiveSupport::SafeBuffer.

Identifier terminal except certain keywords

I'm using Irony framework and I have:
IdentifierTerminal variable = new IdentifierTerminal("variable");
a terminal for identifying an entry terminal.
This variable terminal can hold any string, except for a predefined list of reserved strings.
This identifier does not start or any with quotes or double quotes.
I want something like:
IdentifierTerminal variable = any contiguos string EXCEPT "event", "delegate";
How can I enforce this rule for this terminal?
Have you declared your keywords explicitly? If not, this page: https://en.wikibooks.org/wiki/Irony_-_Language_Implementation_Kit/Grammar/Terminals#Keywords will show you how. It seems that you don't need to explicitly say that an identifier cannot be a keyword, as the parser is able to figure this out. I found the following quote
Finally, in most cases, the Irony scanner does not need to distinguish between keywords and identifiers. It simply tokenizes all alpha-numeric words as identifiers, leaving it to the parser to differentiate them from each other. Some LEX-based solutions try to put too much responsibility on the scanner and make it recognize not only the token itself, but also its role in the surrounding context. This, in turn, requires extensive look-aheads, making the scanner code quite complex. In the author's opinion, identifying the token role is the responsibility of the parser, not the scanner. The scanner should recognize tokens without using any contextual information.
source: http://www.codeproject.com/Articles/22650/Irony-NET-Compiler-Construction-Kit

remove conversion validation message in struts 2 or make it general

In my struts2 application I have field named carrierNo that accepts integer, when i put string in it gives me this validation error message:
*Invalid field value for field "carrierNo".*
i can customize this error message in the properties file like this
invalid.fieldvalue.carrierNo=this field does not accept characters
but i don't want to write a customized message for every non String field in my web application, i want to make it general, i tried the following but it did not work
invalid.fieldvalue.%{getText(fieldName)}=this field does not accept characters
if there is no way to make general, please help me disable this message at all.
then i will use converstion field validator with single message that i define in the properties file.
so my request is to help me make this invalid.fieldvalue.carrierNo general something like this form invalid.fieldvalue.%{getText(fieldName)}
or disable the display of this error message Invalid field value for field "carrierNo".
You could create your own implementation of ConversionErrorInterceptor which finds out the class of failed field and gets your custom message.
Edit:
See source code for ConversionErrorInterceptor. For example you could do something like this in your custom interceptor inside intercept method
// get field by name from action
Field f = invocation.getAction().getClass().getDeclaredField(propertyName);
// get type of field
Class clz = f.getType();
String message = LocalizedTextUtil.findDefaultText(XWorkMessages.DEFAULT_INVALID_FIELDVALUE + "." + clz,
invocationContext.getLocale());
And in your messages.properties file put xwork.default.invalid.fieldvalue.int, xwork.default.invalid.fieldvalue.float, etc.
The easiest way to remove conversion messages is to remove the "conversionError" interceptor from your default stack. One problem with removing it, however, is that IIRC it's also responsible for putting the original (non-converted) value back into fields instead of having them replaced by the value of the failed conversion. This can lead to an unpleasant user experience, IMO.
Making a "... does not accept characters" conversion error message doesn't feel right: conversion errors encompass the entire application, and characters may not be the reason for a conversion error.

How can I retrieve an id from the url in Coldfusion?

I'm updating a site and am struggling to find a way to get an id from the URL. For example I have this:
http://some.html/search.cfm?id=9900000000301
How do I get the id value "9900000000301" from the URL in Coldfusion8?
I have tried url.id plus all sorts of *cgi.query_string* variations, but the number is still out of reach :-(
Thanks for help!
EDIT:
If I dump the URL struct, I'm getting this:
catch - struct
TYPE: default
VALUE: search
Which is not saying much to me.
The url.id should work just fine.
Url.Id will work - with one exception.
If you have created a variable called Url, it is possible (in Adobe CF) to "hide" the Url scope, and thus not be able to access it.
For example, if you have a function with an argument called url, referring to url inside that function will refer to Arguments.Url, not the Url scope. If this is the case, you need to rename the argument to be able to access the proper Url scope.
(Alternatively, switch to a better CFML engine where scope names always takes precedence over unscoped variables, and thus scopes cannot be hidden.)
Depending on how you are looking to use the data, here are two examples. The first checks to see if it was defined and the second sets a variable to the value.
<cfif isDefined("URL.id")>
<cset myVariable = URL.id>
</cfif>
Hope this helps!

Is a url query parameter valid if it has no value?

Is a url like http://example.com/foo?bar valid?
I'm looking for a link to something official that says one way or the other. A simple yes/no answer or anecdotal evidence won't cut it.
Valid to the URI RFC
Likely acceptable to your server-side framework/code
The URI RFC doesn't mandate a format for the query string. Although it is recognized that the query string will often carry name-value pairs, it is not required to (e.g. it will often contain another URI).
3.4. Query
The query component contains non-hierarchical data that, along with
data in the path component (Section 3.3), serves to identify a
resource within the scope of the URI's scheme and naming authority
(if any). ...
... However, as query components
are often used to carry identifying information in the form of
"key=value" pairs and one frequently used value is a reference to
another URI, ...
HTML establishes that a form submitted via HTTP GET should encode the form values as name-value pairs in the form "?key1=value1&key2=value2..." (properly encoded). Parsing of the query string is up to the server-side code (e.g. Java servlet engine).
You don't identify what server-side framework you use, if any, but it is possible that your server-side framework may assume the query string will always be in name-value pairs and it may choke on a query string that is not in that format (e.g. ?bar). If its your own custom code parsing the query string, you simply have to ensure you handle that query string format. If its a framework, you'll need to consult your documentation or simply test it to see how it is handled.
They're perfectly valid. You could consider them to be the equivalent of the big muscled guy standing silently behind the mob messenger. The guy doesn't have a name and doesn't speak, but his mere presence conveys information.
"The "http" scheme is used to locate network resources via the HTTP protocol. This section defines the scheme-specific syntax and semantics for http URLs." http://www.w3.org/Protocols/rfc2616/rfc2616.html
http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]]
So yes, anything is valid after a question mark. Your server may interpret differently, but anecdotally, you can see some languages treat that as a boolean value which is true if listed.
Yes, it is valid.
If one simply want to check if the parameter exists or not, this is one way to do so.
URI Spec
The only relevant part of the URI spec is to know everything between the first ? and the first # fits the spec's definition of a query. It can include any characters such as [:/.?]. This means that a query string such as ?bar, or ?ten+green+apples is valid.
Find the RFC 3986 here
HTML Spec
isindex is not meaningfully HTML5.
It's provided deprecated for use as the first element in a form only, and submits without a name.
If the entry's name is "isindex", its type is "text", and this is the first entry in the form data set, then append the value to result and skip the rest of the substeps for this entry, moving on to the next entry, if any, or the next step in the overall algorithm otherwise.
The isindex flag is for legacy use only. Forms in conforming HTML documents will not generate payloads that need to be decoded with this flag set.
The last time isindex was supported was HTML3. It's use in HTML5 is to provide easier backwards compatibility.
Support in libraries
Support in libraries for this format of URI varies however some libraries do provide legacy support to ease use of isindex.
Perl URI.pm (special support)
Some libraries like Perl's URI provide methods of parsing these kind of structures
$uri->query_keywords
$uri->query_keywords( $keywords, ... )
$uri->query_keywords( \#keywords )
Sets and returns query components that use the keywords separated by "+" format.
Node.js url (no special support)
As another far more frequent example, node.js takes the normal route and eases parsing as either
A string
or, an object of keys and values (using parseQueryString)
Most other URI-parsing APIs following something similar to this.
PHP parse_url, follows as similar implementation but only returns the string for the query. Parsing into an object of k=>v requires parse_string()
It is valid: see Wikipedia, RFC 1738 (3.3. HTTP), RFC 3986 (3. Syntax Components).
isindex deprecated magic name from HTML5
This deprecated feature allows a form submission to generate such an URL, providing further evidence that it is valid for HTML. E.g.:
<form action="#isindex" class="border" id="isindex" method="get">
<input type="text" name="isindex" value="bar"/>
<button type="submit">Submit</button>
</form>
generates an URL of type:
?bar
Standard: https://www.w3.org/TR/html5/forms.html#naming-form-controls:-the-name-attribute
isindex is however deprecated as mentioned at: https://stackoverflow.com/a/41689431/895245
As all other answers described, it's perfectly valid for checking, specially for boolean kind stuff
Here is a simple function to get the query string by name:
function getParameterByName(name, url) {
if (!url) {
url = window.location.href;
}
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
and now you want to check if the query string you are looking for exists or not, you may do a simple thing like:
var exampleQueryString = (getParameterByName('exampleQueryString') != null);
the exampleQueryString will be false if the function can't find the query string, otherwise will be true.
The correct resource to look for this is RFC6570. Please refer to section 3.2.9 where in examples empty parameter is presented as below.
Example Template Expansion
{&x,y,empty} &x=1024&y=768&empty=

Resources