Converting between bases in Ruby - ruby

I'm trying to learn Ruby using problems from this subreddit. I'm working on a problem that's asking me to take a string containing a series of hex values separated by spaces, then convert them to binary and do some work based on the binary values. I have what looks like should be a working solution, but I'm getting errors when I run it. Here's the code:
print "enter: "
vals = gets.chomp.split
for i in 0...vals.length do
vals[i].hex.to_s(2)!
end
vals.each {|x| puts x}
I'm getting the following error messages:
test.rb:6: syntax error, unexpected '!', expecting keyword_end
test.rb:9: syntax error, unexpected end-of-input, expecting keyword_end
From what I understand, the .hex method should return the decimal value of a hex string, and to_s(2)! should convert that integer to a binary string. Obviously, though, I'm not getting something.

The bang after to_s is not a valid syntax on ruby. What you can have is a method ending with !, for example, chomp!. And there is no .to_s! method.
What you are looking for can be achieved by the following code:
print "enter: "
vals = gets.chomp.split
for i in 0...vals.length do
vals[i] = vals[i].hex.to_s(2)
end
vals.each {|x| puts x}

Related

ruby TypeError - no implicit conversion of Fixnum into String?

Im trying to eval this function and appears
this error
TypeError - no implicit conversion of Fixnum into String
eval("File.open('nagai.txt', 'a+') do |f| \n f. puts parts[" + params[:salutation].to_i + "] \n end")
how I could solve
This code is extremely risky and I can't see a reason for doing this in the first place. Remove the eval and you get this very ordinary code:
File.open('nagai.txt', 'a+') do |f|
f.puts parts[params[:salutation]]
end
The error comes from trying to concatenate a Fixnum/Integer to a String in the process of constructing the code you then eval. This code is invalid and yields the same error:
"1" + 1
Ruby isn't like other languages such as JavaScript, PHP or Perl which arbitrarily convert integers to strings and vice-versa. There's a hard separation between the two and any conversion must be specified with things like .to_s or .to_i.
That fixed version should be equivalent. If you need to defer this to some later point in time, you can write a method:
def write_nagai(params)
File.open('nagai.txt', 'a+') do |f|
f.puts parts[params[:salutation]]
end
end

Why won't Ruby return an array without "return"?

def foo
1,2
end
causes syntax error "unexpected ',', expecting keyword_end"
I'd think this is valid Ruby. What's wrong?
You're not returning an array.
You should have this:
def foo
[1, 2]
end
Ruby isn't expecting a comma (,) because it isn't valid syntax. Integers in a simple array should be surrounded by brackets as well as delineated by a comma.
If you used explicit return it will work.
def foo
return 1,2
end
But that wouldn't work with implicit return. To make it work with implicit return you need to give it [1, 2].

Noob and receiving syntax error for google-search code

Pretty much have typed code from this example word for word, and receiving following syntax error message. Please help!!
https://github.com/visionmedia/google-search/blob/master/examples/web.rb
My code:
require "rubygems"
require "google-search"
def find_item uri, query
search = Google::Search::Web.new do |search|
search.query = query
search.size = :large
search.each_response {print "."; #stdout.flush}
end
search.find {|item| item.uri =~ uri}
end
def rank_for query
print "%35s " % query
if item = find_item(/vision\-media\.ca/, query)
puts " #%d" % (item.index +1)
else
puts " Not found"
end
end
rank_for "Victoria Web Training"
rank_for "Victoria Web School"
rank_for "Victoria Web Design"
rank_for "Victoria Drupal"
rank_for "Victoria Drupal Development"
Error message:
Ruby Google Search:9: syntax error, unexpected keyword_end, expecting '}'
Ruby Google Search:11: syntax error, unexpected keyword_end, expecting '}'
Ruby Google Search:26: syntax error, unexpected $end, expecting '}'
You've inadvertently commented out the remainder of line 9:
search.each_response {print "."}
Note that the # character in Ruby denotes a comment; i.e., everything on the same line to the right of the # inclusive is considered comment and is not compiled as Ruby code.
print 'this ' + 'is ' + 'compiled'
#=> this is compiled
print 'this' # + 'is' + 'not'
#=> this
Note that the bracket {} notation encapsulates a single executable line contained within a block. What you're trying to do, however, is to execute two commands. For this, it may be more semantically readable to use Ruby's block notation:
search.each_response do
print '.'
STDOUT.flush
end
Instead of #stdout.flush, type $stdout.flush.
The last line of the do block in find_item is:
search.each_response {print "."; #stdout.flush}
Where the # in Ruby marks the beginning of comment. You've commented out the remainder of the line, but not before opening a bracket {. The lack of it being closed is the source of your error.
In order for your code to be correct, you should change the # to $ to access the global stdout object.

How can I logically OR two include? conditions in Ruby?

I am starting learn Ruby, need some help with the include? method.
The below code works just fine:
x = 'ab.c'
if x.include? "."
puts 'hello'
else
puts 'no'
end
But when I code it this way:
x = 'ab.c'
y = 'xyz'
if x.include? "." || y.include? "."
puts 'hello'
else
puts 'no'
end
If gives me error when I run it:
test.rb:3: syntax error, unexpected tSTRING_BEG, expecting keyword_then or ';' o
r '\n'
if x.include? "." || y.include? "."
^
test.rb:5: syntax error, unexpected keyword_else, expecting end-of-input
Is this because the include? method cannot have handle logic operator?
Thanks
The other answer and comment are correct, you just need to include parenthesis around your argument due to Ruby's language parsing rules, e.g.,
if x.include?(".") || y.include?(".")
You could also just structure your conditional like this, which would scale more easily as you add more arrays to search:
if [x, y].any? {|array| array.include? "." }
puts 'hello'
else
puts 'no'
end
See Enumerable#any? for more details.
It's because of Ruby parser, it can't recognize the difference between the passing an arguments and logical operators.
Just modify your code a little bit to distinguish the arguments and operator for Ruby parser.
if x.include?(".") || y.include?(".")
puts 'hello'
else
puts 'no'
end

Why does executing a string containing function calls using ruby eval fail

I'm quite new to Ruby so I hope this question isn't already answered elsewhere. But I've been searching here and on the internet for quite a while with no results yet.
I am reading in a bunch of file paths from a text file. Each file path has some expressions (i.e. #{...} ) embedded into the string. For instance:
input = 'E:/files/storage/#{high_or_low}/#{left_or_right}/*.dll'
Anyways, I want to evaluate those strings as if they were ruby code and get those expressions replaced. For instance:
def high_or_low
'low'
end
def left_or_right
'left'
end
# It represents a file path on the disk drive
input = 'E:/files/storage/#{high_or_low}/#{left_or_right}/*.dll'
puts input
# Now how do I execute this 'input' string so that it behaves as if it was defined with quotes?
result = eval input
puts result
I purposefully put single quotes around the original input string to show that when the string comes in off the disk, the expression embedded in the string is unevaluated. So how do I evaluate the string with these expressions? Using eval as shown above doesn't seem to work. I get this error:
test_eval.rb:15: compile error (SyntaxError)
test_eval.rb:15: syntax error, unexpected tIDENTIFIER, expecting $end
Thanks
pst pointed you to why it's failing. As an alternative, which may or may not work depending on what your data looks like... but if it's simple strings with method names (and in particular doesn't contain nested "}"'s...
result = input.gsub(/\#{(.*?)}/) {|s| send($1)}
puts result
Ah found it. pst got me started in the correct direction.
So once I wrapped the input variable in quotes like this, it worked:
result = eval '"' + input + '"'
puts result
=> E:/files/storage/low/left/*.dll

Resources