RuboCop style suggestion: "Pass '$:to_i' as an argument to 'Transform' instead of a block." - rubocop

I guess I'm not quite understanding the style suggestion. I'm passing a regexp to Transform, is this considered a "block"? And how do I pass $:key to Transform in this situation?
CAPTURE_CASH_AMOUNT = Transform(/^\$(\d+)$/) do |digits|
digits.to_i
end

[...] is this considered a "block"?
Anything wrapped in do-end is a block in Ruby.
And how do I pass &:key to Transform in this situation?
Ruby implements Symbol#to_proc for you, to allow the shorthand &:method argument for block that send a single method to the yielded object.
In your case, this is equivalent:
CAPTURE_CASH_AMOUNT = Transform(/^\$(\d+)$/, &:to_i)

Related

Is there something like a Safe Navigation Operator that can be used on Arrays?

I have used Safe Navigation Operator for Objects to load on Asynchronous calls and it is pretty amazing. I thought I could reproduce the same for Arrays but it displays a template parse error in my Angular code. I know *ngIf is an alternative solution, but is there a more simpler(by code) way just like the Safe Navigation Operator?
<div class="mock">
<h5>{{data?.title}}</h5> //This works
<h6>{{data?.body}}</h6> //This works
<h6>{{simpleData?[0]}}</h6> // This is what I tried to implement
</div>
Is there something like a Safe Navigation Operator that can be used on Arrays?
Yes, what you are looking for is known as the Optional Chaining operator (JavaScript / TypeScript).
The syntax shown in the MDN JavaScript documentation is:
obj.val?.prop
obj.val?.[expr]
obj.arr?.[index]
obj.func?.(args)
So, to achieve what you want, you need to change your example from:
<h6>{{simpleData?[0]}}</h6>
To:
<h6>{{simpleData?.[0]}}</h6>
^
Also see How to use optional chaining with array in Typescript?.
is there a more simpler(by code) way just like the Safe Navigation Operator?
There is ternary operator.
condition ? expr1 : expr2
<h6>{{simpleData?simpleData[0]:''}}</h6>
Of cause it's a matter of taste, but in such cases I tend to use a shorter approach:
<h6>{{(simpleData || [])[0]}}</h6>
The other answers amount to the same thing, but I find foo && foo[0] to be the most readable. The right side of the logical-and operator won't be evaluated if the left side is falsy, so you safely get undefined (or I guess null, if you don't believe Douglas Crockford.) with minimal extra characters.
For that matter, you asked for a "simpler" solution, but actually *ngIf is probably correct for the use case you gave. If you use any of the answers here, you'll wind up with an empty h6 tag that you didn't need. If you make the tag itself conditional, you can just put foo[0] in the handlebars and be confident that it won't be evaluated when foo is still undefined, plus you never pollute the page with an empty tag.

Polymer hostAttributes Error

I have been following along the Polymer 1.0 Developer guide and I stumbled when getting up to the specific part about hostAttributes.
When I take the example code from the docs:
hostAttributes: {
string-attribute: 'Value',
boolean-attribute: true
tabindex: 0
}
and add it to my prototype, the browser keeps throwing the error:
Uncaught SyntaxError: Unexpected token -
on the lines where there are dashes. Strangely, when I put quotes around string-attribute and boolean-attribute, it renders fine.
Is this an error on my part or is it an error in the docs somehow?
In The way that this example represented string-attribute, string-attribute refers to a string as an attribute that should be set on the label of your element declaration. Also, as you may have noticed by the way you are declaring string-attribute in the example, Javascript assumes that string-attribute is a variable, and variables can not be declared as "my-variable" are declared "myvariable", all strings together.
I think that's the reason why you should declared as follows:
hostAttributes: {
"my-var": 'Value',// Javascript assumes that my-bar is an string
my-var-two: 'value'// Javascript assumes that my-bar-two is a variable (this will fail)
tabindex: 0
}
I hope you have understood me, my English is very bad.
Edit
If a custom elements needs HTML attributes set on it at create-time, these may be declared in a hostAttributes property on the prototype, where keys are the attribute name and values are the values to be assigned. Values should typically be provided as strings, as HTML attributes can only be strings;
hostAttributes: {
string-attribute: 'Value', //string-attribute is a key, should be inside "" because javascript's keys doesn't accepts "-"
boolean-attribute: true//will fail because is not a key
tabindex: 0//this works because for javascript this is a correct key
}
...however, the standard serialize method is used to convert values to
strings, so true will serialize to an empty attribute, and false will
result in no attribute set, and so forth
As you can realize, only serialized string values, never mentioned that the keys are serialized as string as well. As I mentioned before, my English is bad and I understood that.

HTML input pattern: all except URL

Is it real to set input pattern to all as usually, but with one exception: url are not acceptable. I mean for example all input patterns are ok, but:
ftp://example.com
http://example.com
https://example.com
we could not enter...
is it real to do without using javascript or no ?
With JavaScript and using the regex found here: What is the best regular expression to check if a string is a valid URL?, you could do something like this:
function isValid(inputVal){
return !/((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w]+#)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w]+#)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%#.\w_]*)#?(?:[\w]*))?)/.test(inputVal);
}
isValid(document.getElementById("inputID").value);
EDIT
Without JavaScript you can do it like such
<input pattern="^(?!((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w]+#)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w]+#)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%#.\w_]*)#?(?:[\w]*))?))" >
^ # start of the string
(?! # start negative look-ahead
.* # zero or more characters of any kind (except line terminators)
foobar # foobar
)
Choose the URL validation regex from internet ( or write your own :) ).
Put it in negative look-ahead (?!).
Add .* for match everything else.
Use your new regex in pattern attribute of the inputs.
For example if the URL validation regex is ^(((https?)|(ftp)):\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$ the inputs will be like
<input type="text" pattern="^(?!(((https?)|(ftp)):\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?).*$" />
Note: not every regex will work if you add it in negative look-ahead so just use JavaScript and inverse the result of the original regex. Also your input must be inside a form to trigger the patern validation (on form submit).
The question indicates you already know the regex and just want to know whether you should be using Javascript (or HTML) for this. The answer would be: probably not.
If you are filtering input for - say - a forum, using Javascript would be a bad idea because it runs locally, so the user can easily avoid the check. Use a server-sided language (most-probably PHP) to do the check.

HTML rendered incorrectly in .NET

I am trying to take the string "<BR>" in VB.NET and convert it to HTML through XSLT. When the HTML comes out, though, it looks like this:
<BR>
I can only assume it goes ahead and tries to render it. Is there any way I can convert those </> back into the brackets so I get the line break I'm trying for?
Check the XSLT has:
<xsl:output method="html"/>
edit: explanation from comments
By default XSLT outputs as XML(1) which means it will escape any significant characters. You can override this in specific instances with the attribute disable-output-escaping="yes" (intro here) but much more powerful is to change the output to the explicit value of HTML which confides same benefit globally, as the following:
For script and style elements, replace any escaped characters (such
as & and >) with their actual values
(& and >, respectively).
For attributes, replace any occurrences of > with >.
Write empty elements such as <br>, <img>, and <input> without
closing tags or slashes.
Write attributes that convey information by their presence as
opposed to their value, such as
checked and selected, in minimized
form.
from a solid IBM article covering the subject, more recent coverage from stylusstudio here
If HTML output is what you desire HTML output is what you should specify.
(1) There is actually corner case where output defaults to HTML, but I don't think it's universal and it's kind of obtuse to depend on it.
Try wraping it with <xsl:text disable-output-escaping="yes"><br></xsl:text>
Don't know about XSLT but..
One workaround might be using HttpUtility.HtmlDecode from System.Web namespace.
using System;
using System.Web;
class Program
{
static void Main()
{
Console.WriteLine(HttpUtility.HtmlDecode("<br>"));
Console.ReadKey();
}
}
...
Got it! On top of the selected answer, I also did something similar to this on my string:
htmlString = htmlString.Replace("<","<")
htmlString = htmlString.Replace(">",">")
I think, though, that in the end, I may just end up using <pre> tags to preserve everything.
The string "<br>" is already HTML so you can just Response.Write("<br>").
But you meantion XSLT so I imagine there some transform going on. In that case surely the transform should be inserting it at the correct place as a node. A better question will likely get a better answer

How can I remove an entire HTML tag (and its contents) by its class using a regex?

I am not very good with Regex but I am learning.
I would like to remove some html tag by the class name. This is what I have so far :
<div class="footer".*?>(.*?)</div>
The first .*? is because it might contain other attribute and the second is it might contain other html stuff.
What am I doing wrong? I have try a lot of set without success.
Update
Inside the DIV it can contain multiple line and I am playing with Perl regex.
As other people said, HTML is notoriously tricky to deal with using regexes, and a DOM approach might be better. E.g.:
use HTML::TreeBuilder::XPath;
my $tree = HTML::TreeBuilder::XPath->new;
$tree->parse_file( 'yourdocument.html' );
for my $node ( $tree->findnodes( '//*[#class="footer"]' ) ) {
$node->replace_with_content; # delete element, but not the children
}
print $tree->as_HTML;
You will also want to allow for other things before class in the div tag
<div[^>]*class="footer"[^>]*>(.*?)</div>
Also, go case-insensitive. You may need to escape things like the quotes, or the slash in the closing tag. What context are you doing this in?
Also note that HTML parsing with regular expressions can be very nasty, depending on the input. A good point is brought up in an answer below - suppose you have a structure like:
<div>
<div class="footer">
<div>Hi!</div>
</div>
</div>
Trying to build a regex for that is a recipe for disaster. Your best bet is to load the document into a DOM, and perform manipulations on that.
Pseudocode that should map closely to XML::DOM:
document = //load document
divs = document.getElementsByTagName("div");
for(div in divs) {
if(div.getAttributes["class"] == "footer") {
parent = div.getParent();
for(child in div.getChildren()) {
// filter attribute types?
parent.insertBefore(div, child);
}
parent.removeChild(div);
}
}
Here is a perl library, HTML::DOM, and another, XML::DOM
.NET has built-in libraries to handle dom parsing.
In Perl you need the /s modifier, otherwise the dot won't match a newline.
That said, using a proper HTML or XML parser to remove unwanted parts of a HTML file is much more appropriate.
<div[^>]*class="footer"[^>]*>(.*?)</div>
Worked for me, but needed to use backslashes before special characters
<div[^>]*class=\"footer\"[^>]*>(.*?)<\/div>
Partly depends on the exact regex engine you are using - which language etc. But one possibility is that you need to escape the quotes and/or the forward slash. You might also want to make it case insensitive.
<div class=\"footer\".*?>(.*?)<\/div>
Otherwise please say what language/platform you are using - .NET, java, perl ...
Try this:
<([^\s]+).*?class="footer".*?>([.\n]*?)</([^\s]+)>
Your biggest problem is going to be nested tags. For example:
<div class="footer"><b></b></div>
The regexp given would match everything through the </b>, leaving the </div> dangling on the end. You will have to either assume that the tag you're looking for has no nested elements, or you will need to use some sort of parser from HTML to DOM and an XPath query to remove an entire sub-tree.
This will be tricky because of the greediness of regular expressions, (Note that my examples may be specific to perl, but I know that greediness is a general issue with REs.) The second .*? will match as much as possible before the </div>, so if you have the following:
<div class="SomethingElse"><div class="footer"> stuff </div></div>
The expression will match:
<div class="footer"> stuff </div></div>
which is not likely what you want.
why not <div class="footer".*?</div> I'm not a regex guru either, but I don't think you need to specify that last bracket for your open div tag