Why Does White-Space Affect Ruby Function Calls

Why does white-space affect ruby function calls?

the thing is, that method in ruby can be run with or without parentheses.
for example, you can run Array.new 1,2 and ruby knows that it receives the arguments after the space. and you can also run Array.new(1,2) and ruby knows the args are inside the parentheses.

but, when you run Array.new (1,2) , ruby thinks it will receive arguments after the space but actually it receives a tuple (1,2), and basicaly its exactly the same as Array.new((1,2))

so bottom line:

Array.new (1,2) == Array.new((1,2)) and thats a syntax error because (1, 2) literal is not a valid one

Ruby: How can I kill warning: `*' interpreted as argument prefix ?

If you're going to use method-calling-parentheses then you must avoid putting a space between the method name and the opening parentheses:

if "string".start_with?(*hash.keys)
puts "ok"
else
puts "ng"
end

Also, then is rather archaic so we'll pretend that was never there. If there is a space between the method name and the opening parentheses then your parentheses are interpreted as expression-grouping-parentheses and that's where your syntax error comes from.

Once you add the method-calling-parentheses you remove any possible hint of ambiguity as to what your * is supposed to mean and the warning should go away.


BTW, the warning you're getting in this case is rather, um, silly. On second thought, the warning isn't so silly because Ruby can be whitespace sensitive in surprising ways. This:

o.m *x

can be interpreted as:

o.m(*x)

or as:

o.m() * x

but these:

o.m * x
o.m*x
o.m* x

can be interpreted in the same ways. Of course, all three of those are interpreted as o.m() * x and only o.m *x is seen as o.m(*x). Sane whitespace usage would suggest that o.m *x is obviously a splat whereas o.m * x is obviously a multiplication but a couple days on SO should convince you that whitespace usage is hardly sane or consistent.

That said, -w's output in the Real World tends to be so voluminous and noisy that -w is nearly useless.

Ruby whitespace: Is { :a = 1 } better than {:a = 1}?

Most of the Ruby code I see (and hopefully all the code I write) uses this style:

{ :key => 'value' }

This is what I have gotten used to and internalized.

When all is said and done, this one particular style issue is not of paramount importance. That said, the Ruby community (as do others) believes it is important to match your style (a) to the project you are working with and (b) to the community of code as a whole. That's why I recommend to use the extra white spaces.

BTW, this is a good Ruby style guide:
http://www.caliban.org/ruby/rubyguide.shtml#style

Flex and Bison - Grammar that sometimes care about spaces

Without having a full specification of the syntax you are trying to parse, it's not easy to give a precise answer. In the following, I'm assuming that those are the only two places where the presence (or absence) of whitespace between two tokens affects the parse.

Differentiating between f(...) and f (...) occurs in a surprising number of languages. One common strategy is for the lexer to recognize an identifier which is immediately followed by an open parenthesis as a "FUNCTION_CALL" token.

You'll find that in most awk implementations, for example; in awk, the ambiguity between a function call and concatenation is resolved by requiring that the open parenthesis in a function call immediately follow the identifier. Similarly, the C pre-processor macro definition directive distinguishes between #define foo(A) A (the definition of a macro with arguments) and #define foo (A) (an ordinary macro whose expansion starts with a ( token.

If you're doing this with (f)lex, you can use the / trailing-context operator:

[[:alpha:]_][[:alnum:]_]*/'('   { yylval = strdup(yytext); return FUNC_CALL; }
[[:alpha:]_][[:alnum:]_]* { yylval = strdup(yytext); return IDENT; }

The grammar is now pretty straight-forward:

call: FUNC_CALL '(' expression_list ')'   /* foo(1, 2) */
| IDENT expression_list /* foo (1, 2) */
| IDENT /* foo * 3 */

This distinction will not be useful in all syntactic contexts, so it will often prove useful to add a non-terminal which will match either identifier form:

name: IDENT | FUNC_CALL

But you will need to be careful with this non-terminal. In particular, using it as part of the expression grammar could lead to parser conflicts. But in other contexts, it will be fine:

func_defn: "def" name '(' parameters ')' block "end"

(I'm aware that this is not the precise syntax for Ruby function definitions. It's just for illustrative purposes.)

More troubling is the other ambiguity, in which it appears that the unary operators + and - should be treated as part of an integer literal in certain circumstances. The behaviour of the Ruby parser suggests that the lexer is combining the sign character with an immediately following number in the case where it might be the first argument to a function. (That is, in the context <identifier><whitespace><sign><digits> where <identifier> is not an already declared local variable.)

That sort of contextual rule could certainly be added to the lexical scanner using start conditions, although it's more than a little ugly. A not-fully-fleshed out implementation, building on the previous:

%x SIGNED_NUMBERS
%%

[[:alpha:]_][[:alnum:]_]*/'(' { yylval.id = strdup(yytext);
return FUNC_CALL; }
[[:alpha:]_][[:alnum:]_]*/[[:blank:]] { yylval.id = strdup(yytext);
if (!is_local(yylval.id))
BEGIN(SIGNED_NUMBERS);
return IDENT; }
[[:alpha:]_][[:alnum:]_]*/ { yylval.id = strdup(yytext);
return IDENT; }
<SIGNED_NUMBERS>[[:blank:]]+ ;
/* Numeric patterns, one version for each context */
<SIGNED_NUMBERS>[+-]?[[:digit:]]+ { yylval.integer = strtol(yytext, NULL, 0);
BEGIN(INITIAL);
return INTEGER; }
[[:digit:]]+ { yylval.integer = strtol(yytext, NULL, 0);
return INTEGER; }

/* ... */
/* If the next character is not a digit or a sign, rescan in INITIAL state */
<SIGNED_NUMBERS>.|\n { yyless(0); BEGIN(INITIAL); }

Another possible solution would be for the lexer to distinguish sign characters which follow a space and are directly followed by a digit, and then let the parser try to figure out whether or not the sign should be combined with the following number. However, this will still depend on being able to distinguish between local variables and other identifiers, which will still require the lexical feedback through the symbol table.

It's worth noting that the end result of all this complication is a language whose semantics are not very obvious in some corner cases. The fact that f+3 and f +3 produce different results could easily lead to subtle bugs which might be very hard to detect. In many projects using languages with these kinds of ambiguities, the project style guide will prohibit legal constructs with unclear semantics. You might want to take this into account in your language design, if you have not already done so.

How do I remove repeated spaces in a string?

>> str = "foo  bar   bar      baaar"
=> "foo bar bar baaar"
>> str.split.join(" ")
=> "foo bar bar baaar"
>>

remove whitespace from html document using ruby

str.gsub!(/\n\t/, " ").gsub!(/>\s*</, "><")

That first gsub! replaces all line breaks and tabs with spaces, the second removes spaces between tags.

You will end up with multiple spaces inside your tags, but if you just removed all \n and \t, you would get something like "not be removed.Butline breaks", which is not very readable. Another Regular Expression or the aforementioned .squeeze(" ") could take care of that.

What does Ruby have that Python doesn't, and vice versa?

You can have code in the class definition in both Ruby and Python. However, in Ruby you have a reference to the class (self). In Python you don't have a reference to the class, as the class isn't defined yet.

An example:

class Kaka
puts self
end

self in this case is the class, and this code would print out "Kaka". There is no way to print out the class name or in other ways access the class from the class definition body in Python.

Split string in ruby based on whitespace

In ruby this would simply be String#split:

2.2.3 :001 > str = 'I am a student of xyz University'
=> "I am a student of xyz University"
2.2.3 :002 > str.split
=> ["I", "am", "a", "student", "of", "xyz", "University"]

Remove white space in templates when using ERB class in Ruby

Hay, when you want to use the <%- -%> tag (this prevents the if output) you have to pass - to trim_mode option of ERB.new to use it.

See the following example:

Change you test.erb file to the following code:

Hello
<% if (@x) -%>
XXX
<% end -%>
Goodbye

When you instance ERB, pass the option like this:

renderer = ERB.new(File.read('test.erb'), nil, '-')

Now, the <%- -%> tags will works fine, hope this helps!



Related Topics



Leave a reply



Submit