I'm making a basic translator in Ruby (1.9.3). I'm pulling from a local test file ('a.txt') and using gsub to replace certain matches to mimic a translation from contemporary English to Middle/Early Modern English. I've run into a readability issue:
How can I make the large amount of gsub usage easier to read? I've attempted to use multiple lines starting with
def translate
@text.gsub(/my/, 'mine')
@text.gsub(/\sis\s/, ' be ')
end
but this only prints the final gsub. I can only assume that the second request overwrites the first. I would like to avoid creating a giant line of gsub requests and I cannot seem to find a suitable answer.
Here is a sample of my current program:
lines = File.readlines('a.txt')
@text = lines.join
def translate
@text.gsub(/my/, 'mine').gsub(/\sis\s/, ' be ').gsub(/y\s/, 'ye ').gsub(/t\s/, 'te ').gsub(/t\,/, 'te,').gsub(/t\./, 'te.')
end
puts translate
I apologize in advance if this request seems thoroughly basic. Cheers!
gsub! is a String class method in Ruby which is used to return a copy of the given string with all occurrences of pattern substituted for the second argument. If no substitutions were performed, then it will return nil. If no block and no replacement is given, an enumerator is returned instead.
The sub() and gsub() function in R is used for substitution as well as replacement operations. The sub() function will replace the first occurrence leaving the other as it is. On the other hand, the gsub() function will replace all the strings or values with the input strings.
gsub stands for global substitution (replace everywhere). It replaces every occurrence of a regular expression (original string) with the replacement string in the given string. The third argument is optional. If it is not specified, then $0 is used.
gsub (s, pattern, repl [, n]) Returns a copy of s in which all (or the first n , if given) occurrences of the pattern have been replaced by a replacement string specified by repl , which can be a string, a table, or a function. gsub also returns, as its second value, the total number of matches that occurred.
The second call doesn't override the first. The first call returns a copy of @text
with the substitution made, but you aren't doing anything with that returned value. If you want to modify @text
, you need to use gsub!
instead. If you don't want to modify @text
, then you need to chain the gsub
calls instead. For instance, if you have the mapping Hash from slivu's answer, this will return the translated text without actually modifying the @text
instance variable:
def translate
RegexMap.inject(@text) do |string, mapping|
string.gsub(*mapping)
end
end
The block passed to inject
gets called once per mapping (key/value pair in RegexMap
). The first time, string
is the value passed to inject
- namely, @text
. After that, each subsequent call gets the return value of the previous call passed in as its string
value. So it's as if you did this, but with the set of mappings more easily configurable:
@text.gsub(/my/,'mine').gsub(/\sis\s/, ' be ').gsub(/y\s/,'ye ').gsub....
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With