Spacing Around Parentheses in Ruby

Spacing around parentheses in Ruby

Anyone that puts a space before a parameter-list parentheses gets what they deserve, I say!

The problem is that it's closing out the call to button_to in the second example (space before the parentheses) and doesn't know what to do next.

Why does Ruby sometimes throw an error when a function is called with a space before the parentheses?

Using Ruby 2.6.3 I get the following warning when run with ruby -w.

test.rb:1: warning: parentheses after method name is interpreted as an argument list, not a decomposed argument

This is referring to Array Decomposition where you can unpack the elements of an Array argument into individual variables.

def bar((a,b))
puts "a: #{a}, b: #{b}"
end

# a: first, b: second
bar ['first', 'second', 'third']

What's wrong with def foo (i)? def foo i is legal; parenthesis around the arguments are optional. However def foo (i) is ambiguous. It can be interpreted as a single argument def foo(i) or an array decomposition def foo((i)).

Because this is ambiguous, different interpreters may have different... interpretations. /p>

How to remove everything in between parenthesis and trailing space from string?

Try this:

x = "2(2) , 12(3) , 20(2) , 21(5)"
x.gsub(/\(.*?\)/, '')

Sample Image

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 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

Removing text within parentheses and trailing spaces

It's really just a minor modification to make it capture the spaces, too, if there are any:

summary.gsub!(/\s*\([^\)]*\)/, '')

That will only capture leading spaces. If you want leading and trailing:

summary.gsub!(/\s*\([^\)]*\)\s*/, '')

Regex Ruby How to group every word within parentheses

You may use

.scan(/(?:\G(?!\A)\s*,\s*|\sLOREM\s+\()\K\w+(?=[^()]*\)\z)/

See the Ruby demo and the Rubular regex demo. You may replace \w+ with [[:alnum:]]+, or \p{L}+ (to only match letters), or [^\s,()]+ (to match any 1+ chars other than whitespace, ,, ( and )), it all depends on what you want to match inside the paretheses.

Details

  • (?:\G(?!\A)\s*,\s*|\sLOREM\s+\() - either the end of the previous successful match and a , enclosed with 0+ whitespaces, or whitespace, LOREM, 1+ whitespaces and (
  • \K - omit the text matched so far
  • \w+ - consume 1+ word chars
  • (?=[^()]*\)\z) - immediately to the right, there must be 0 or more chars other than ( and ) and then ) at the end of the string.

Split string in Ruby, ignoring contents of parentheses?

Try this:

s = 'A +4, B +6, C (hello, goodbye) +5, D +3'
tokens = s.scan(/(?:\(.*?\)|[^,])+/)
tokens.each {|t| puts t.strip}

Output:

A +4
B +6
C (hello, goodbye) +5
D +3

A short explanation:

(?:        # open non-capturing group 1
\( # match '('
.*? # reluctatly match zero or more character other than line breaks
\) # match ')'
| # OR
[^,] # match something other than a comma
)+ # close non-capturing group 1 and repeat it one or more times

Another option is to split on a comma followed by some spaces only when the first parenthesis that can be seen when looking ahead is an opening parenthesis (or no parenthesis at all: ie. the end of the string):

s = 'A +4, B +6, C (hello, goodbye) +5, D +3'
tokens = s.split(/,\s*(?=[^()]*(?:\(|$))/)
tokens.each {|t| puts t}

will produce the same output, but I find the scan method cleaner.

What are the rules for spaces in Ruby?

Because methods can be called with no parentheses, this:

a.count - 1

Means subtract 1 from a.count, whereas

a.count -1 # is like a.count(-1)

Means call the method a.count with -1 as an argument. It doesn't happen when a is an integer because integers don't have the count method. You just have to be careful as you type.

trying to find a file/line for: .(eval):289: warning: don't put space before argument parentheses

The file and line number are contained in the backtrace. However, in your case, the warning is inside a string being evaled at runtime. Which means there is no file. (Actually, the eval method does take optional arguments for the file name and line number that should be displayed in a backtrace, but in this case whoever wrote the code in question unfortunately forgot to pass those arguments.)

I fear that you have no other choice than to manually examine every single call to eval in your entire codebase, and that includes Rails, your testing framework, your entire application, your tests, your plugins, your helpers, the ruby standard library, ...

Of course, you should be aware that the problem might not be obvious as in

eval 'foo (bar, baz)'

It could also be something like

def foo(*args)
puts args.join
end

bar = 'Hello'
baz = 'World'

foostr = 'foo' # in one file
barstr = 'bar' # in another file in a different directory
bazstr = 'baz' # in another file in a different directory
argstr = "(#{barstr}, #{bazstr})" # in yet another file
$, = ' ' # in some third-party plugin
str = [foostr, argstr].join # in a fourth file
eval str # somewhere else entirely
eval str, binding, __FILE__, __LINE__ # this is how it *should* be done

Note the difference between the two warning messages: the first one reads exactly like the one you posted, but the second one has the filename instead of (eval) and the line number inside the file instead of the line number inside the eval string.

By the way: the line number 289 in the warning message is the line number inside the evald string! In other words: somewhere in your application there is a string being evald, which is at least 289 lines long! (Actually, it is more likely that this done not in your application but rather in Rails. The Rails router used to be a particularly bad offender, I don't know if this is still the case.)



Related Topics



Leave a reply



Submit