When Should I use expression interpolation in Ruby? - ruby-on-rails

I have confusion for using expression interpolation in method. Initially I thought I can pass any kind of expression like let's say name.capitalize, but I can pass without expression interpolation too. Here is the two cases. Just execute below two methods on irb, I have same result for both method. I am using Ruby 1.9.3
1.
def say_goodnight(name)
result = "Good night, " + name.capitalize
return result
end
puts say_goodnight('uncle')
2.
def say_goodnight(name)
result = "Good night, #{name.capitalize}"
return result
end
puts say_goodnight('uncle')
Both way it will produce output like
Good night, Uncle
So my question is When Should I use expression interpolation in Ruby? and When Should I use parameter in Ruby?

Whichever reads cleaner is generally better. For example, if the string contains a number of variable references, each separated by a few characters, the "+" form of the expression can become complex and unclear, while an interpolated string is more obvious. On the other hand, if the expression(s) are relatively complex, it's better to separate them from other components of the string.
So, I think the following:
"Hello #{yourname}, my name is #{myname} and I'm #{mood} to see you."
is clearer than
"Hello " + yourname + ", my name is " + myname + " and I'm " + mood + "to see you."
But if I had complex expressions, I might want to separate those onto different source code lines, and those are better connected with "+".

I'm with #djconnel–use whichever reads the best, communicates the most information, eases modification and/or extension, makes debugging simple, and so on.
This was just discussed yesterday; see Strange Ruby Syntax?
In your specific example, I'd use string interpolation, because the method is really just:
def say_goodnight(name)
"Good night, #{name.capitalize}"
end

Related

What Lua pattern behaves like a regex negative lookahead?

my problem is I need to write a Lua code to interpret a text file and match lines with a pattern like
if line_str:match(myPattern) then do myAction(arg) end
Let's say I want a pattern to match lines containing "hello" in any context except one containing "hello world". I found that in regex, what I want is called negative lookahead, and you would write it like
.*hello (?!world).*
but I'm struggling to find the Lua version of this.
Let's say I want a pattern to match lines containing "hello" in any context except one containing "hello world".
As Wiktor has correctly pointed out, the simplest way to write this would be line:find"hello" and not line:find"hello world" (you can use both find and match here, but find is probably more performant; you can also turn off pattern matching for find).
I found that in regex, what I want is called negative lookahead, and
you would write it like .*hello (?!world).*
That's incorrect. If you checked against the existence of such a match, all it would tell you would be that there exists a "hello" which is not followed by a "world". The string hello hello world would match this, despite containing "hello world".
Negative lookahead is a questionable feature anyways as it isn't trivially provided by actually regular expressions and thus may not be implemented in linear time.
If you really need it, look into LPeg; negative lookahead is implemented as pattern1 - pattern2 there.
Finally, the RegEx may be translated to "just Lua" simply by searching for (1) the pattern without the negative part (2) the pattern with the negative part and checking whether there is a match in (1) that is not in (2) simply by counting:
local hello_count = 0; for _ in line:gmatch"hello" do hello_count = hello_count + 1 end
local helloworld_count = 0; for _ in line:gmatch"helloworld" do helloworld_count = helloworld_count + 1 end
if hello_count > helloworld_count then
-- there is a "hello" not followed by a "world"
end

Using Ruby, how can I convert a string to an array when there may be variable whitespace between terms?

Imagine I have a string like this: "hello:world, foo:bar,biz:baz, last:term "
And I want to convert it to an array ["hello:world", "foo:bar", "biz:baz", "last:term"]
Essentially I want to split by comma, but also by a variable amount of whitespace. I could do the split and then go through each term and strip whitespace from either side, but I'm hoping there is a simpler way - maybe using Regexp? (I'm very unfamiliar with how to use Regexp). I'm using Ruby on Rails.
You can use scan with a Regexp:
string = "hello:world, foo:bar,biz:baz, last:term "
string.scan(/[^\s,]+/)
#=> ["hello:world", "foo:bar", "biz:baz", "last:term"]
Or you could use split to split the string at the , and the strip to remove the unwanted whitespace.
string = "hello:world, foo:bar,biz:baz, last:term "
string.split(',').map(&:strip)
#=> ["hello:world", "foo:bar", "biz:baz", "last:term"]
I would probably prefer the second version because it is easier to read and understand. Additionally, I wouldn't be surprised if the simple string methods of the second version would perform better for small strings because Regexps are pretty expensive and usually only worth it for more complex or bigger tasks.

Match a word or whitespaces in Lua

(Sorry for my broken English)
What I'm trying to do is matching a word (with or without numbers and special characters) or whitespace characters (whitespaces, tabs, optional new lines) in a string in Lua.
For example:
local my_string = "foo bar"
my_string:match(regex) --> should return 'foo', ' ', 'bar'
my_string = " 123!#." -- note: three whitespaces before '123!#.'
my_string:match(regex) --> should return ' ', ' ', ' ', '123!#.'
Where regex is the Lua regular expression pattern I'm asking for.
Of course I've done some research on Google, but I couldn't find anything useful. What I've got so far is [%s%S]+ and [%s+%S+] but it doesn't seem to work.
Any solution using the standart library, e.g. string.find, string.gmatch etc. is OK.
Match returns either captures or the whole match, your patterns do not define those. [%s%S]+ matches "(space or not space) multiple times more than once", basically - everything. [%s+%S+] is plain wrong, the character class [ ] is a set of single character members, it does not treat sequences of characters in any other way ("[cat]" matches "c" or "a"), nor it cares about +. The [%s+%S+] is probably "(a space or plus or not space or plus) single character"
The first example 'foo', ' ', 'bar' could be solved by:
regex="(%S+)(%s)(%S+)"
If you want a variable number of captures you are going to need the gmatch iterator:
local capt={}
for q,w,e in my_string:gmatch("(%s*)(%S+)(%s*)") do
if q and #q>0 then
table.insert(capt,q)
end
table.insert(capt,w)
if e and #e>0 then
table.insert(capt,e)
end
end
This will not however detect the leading spaces or discern between a single space and several, you'll need to add those checks to the match result processing.
Lua standard patterns are simplistic, if you are going to need more intricate matching, you might want to have a look at lua lpeg library.

What does #{ } mean in Ruby? [duplicate]

This question already has answers here:
What does #{...} mean?
(3 answers)
Closed 8 years ago.
I know that this may be a very basic question but i'm struggling to find a clear answer. What does using this, #{} , mean in Ruby? What does it do?
Thanks
It is used for String interpolation: ( wikipedia, ctrl+f "ruby" )
apples = 4
puts "I have #{apples} apples"
# or
puts "I have %s apples" % apples
# or
puts "I have %{a} apples" % {a: apples}
The output will be:
I have 4 apples
String interpolation, Definition:
In Ruby, string interpolation refers to the ability of double-quoted strings to execute Ruby code and replace portions of that strings (denoted by #{ ... }) with the evaluation of that Ruby code.
It is the most common way to inject data (usually the value of a variable, but it can be the evaluation of any Ruby code) into the middle of a string.
A thing to know:
puts "This User name is #{User.create(username: 'Bobby')}!"
This will make an implicit call of .to_s on the User's instance object.
If you defined the method .to_s on the User model:
class User
def to_s
self.username
end
It would output:
puts "This User name is #{User.create(username: 'Bobby')}"
# => "This User name is Bobby"
It is for String Interpolation..
In Ruby, there are three ways of interpolation, and #{} is just one way.
apples = 4
puts "I have #{apples} apples"
# or
puts "I have %s apples" % apples
# or
puts "I have %{a} apples" % {a: apples}
It's called String Interpolation
In Ruby, string interpolation refers to the ability of double-quoted strings to execute Ruby code and replace portions of that strings (denoted by #{ ... }) with the evaluation of that Ruby code. It is the most common way to inject data (usually the value of a variable, but it can be the evaluation of any Ruby code) into the middle of a string.
print "What is your name? "
name = gets.chomp
puts "Hello, #{name}"
Note that any code can go inside the braces, not just variable names. Ruby will evaluate that code and whatever is returned it will attempt to insert it into the string. So you could just as easily say "Hello, #{gets.chomp}" and forget about the name variable. However, it's good practice not to put long expressions inside the braces.
Author: Michael Morin
That allows you to evaluate arbitrary ruby code within a string (double quotes only). So for example, in something like PHP you'd do
$my_var = "The value of a = " . $a;
But in ruby, you'd just do
my_var = "The value of a = #{a}"
This only works if the string is in double quotes, and NOT single quotes. If you us single quotes then you'll get the #{...} appear in the text
You use it to represent a variable you want to print or puts out. For example:
puts "#{var}" would puts out the value stored within your variable var.

Split lua string into characters

I only found this related to what I am looking for: Split string by count of characters but it is not useful for what I mean.
I have a string variable, which is an ammount of 3 numbers (can be from 000 to 999). I need to separate each of the numbers (characters) and get them into a table.
I am programming for a game mod which uses lua, and it has some extra functions. If you could help me to make it using: http://wiki.multitheftauto.com/wiki/Split would be amazing, but any other way is ok too.
Thanks in advance
Corrected to what the OP wanted to ask:
To just split a 3-digit number in 3 numbers, that's even easier:
s='429'
c1,c2,c3=s:match('(%d)(%d)(%d)')
t={tonumber(c1),tonumber(c2),tonumber(c3)}
The answer to "How do I split a long string composed of 3 digit numbers":
This is trivial. You might take a look at the gmatch function in the reference manual:
s="123456789"
res={}
for num in s:gmatch('%d%d%d') do
res[#res+1]=tonumber(num)
end
or if you don't like looping:
res={}
s:gsub('%d%d%d',function(n)res[#res+1]=tonumber(n)end)
I was looking for something like this, but avoiding looping - and hopefully having it as one-liner. Eventually, I found this example from lua-users wiki: Split Join:
fields = {str:match((str:gsub("[^"..sep.."]*"..sep, "([^"..sep.."]*)"..sep)))}
... which is exactly the kind of syntax I'd like - one liner, returns a table - except, I don't really understand what is going on :/ Still, after some poking about, I managed to find the right syntax to split into characters with this idiom, which apparently is:
fields = { str:match( (str:gsub(".", "(.)")) ) }
I guess, what happens is that gsub basically puts parenthesis '(.)' around each character '.' - so that match would consider those as a separate match unit, and "extract" them as separate units as well... But I still don't get why is there extra pair of parenthesis around the str:gsub(".", "(.)") piece.
I tested this with Lua5.1:
str = "a - b - c"
fields = { str:match( (str:gsub(".", "(.)")) ) }
print(table_print(fields))
... where table_print is from lua-users wiki: Table Serialization; and this code prints:
"a"
" "
"-"
" "
"b"
" "
"-"
" "
"c"

Resources