URL Encoding in ruby - ruby

I have a block of code:
temp = "Cancel"
puts CGI::escape(words[1])
puts "\n"
puts CGI::escape(temp)
puts "\n"
puts words[1]
puts "\n"
puts temp
puts "\n"
My output is:
%00C%00a%00n%00c%00e%00l%00
Cancel
Cancel
Cancel
I think it's fair to assume that the issue here is the way I set up my words array. However, I was wondering if this is common behavior which has a solution? If not, what could I be doing wrong that would cause this?
My words array is set up by reading data from a file, then splitting each line and extracting the information I need, so it's nothing too complex.

You have NUL bytes in your string. puts just ignores them.
1.9.2p290 :016 > puts "Fo\0oooo"
Fooooo
=> nil
with inspect you can see them:
1.9.2p290 :017 > puts "Fo\0oooo".inspect
"Fo\u0000oooo"
=> nil
and here the output of CGI::escape
1.9.2p290 :018 > puts CGI::escape("Fooo\0ooo")
Fooo%00ooo
=> nil
edit:
The quick and dirty solution would be to just remove them:
"Fooooo\0ooo".gsub(/\0/, "")
=> "Foooooooo"
but as you have NUL bytes in front of every char, you should better check your code for reading the file. If you'd provide the code, it would be easier to come up with a solution.

Related

Why does "puts 'foo'" and puts "foo\n" result in the same output in Ruby? [duplicate]

This question already has answers here:
Why doesn't puts() print in a single line?
(3 answers)
Closed 5 years ago.
This is from the irb:
irb(main):001:0> puts "abc"
abc
=> nil
irb(main):002:0> puts "abc\n"
abc
=> nil
irb(main):003:0> puts "abc\n\n"
abc
=> nil
As you can see, puts "abc" puts a newline after "abc", as it should. However, puts "abc\n" also puts a single newline, whereas I would expect that there would be two newlines.
To me, the output of puts "abc\n\n" is what I would expect from puts "abc\n".
Why is this the case?
After reading Cary Swoveland's comment I've realized that it is not at all obvious how puts works, because its documentation is quite scarce:
puts(obj, ...) → nil
Equivalent to
$stdout.puts(obj, ...)
It doesn't even bother to explain what $stdout is, nor does it provide a link.
$stdout is one of Ruby's pre-defined global variables. It refers to the standard output which in Ruby happens to be an instance of IO:
$stdout
#=> #<IO:<STDOUT>>
So "Equivalent to $stdout.puts(obj, ...)" means that we have to read the documentation for IO#puts:
Writes the given object(s) to ios. Writes a newline after any that do not already end with a newline sequence. Returns nil.
There you go: puts only adds a newline if the object does not already ends with one.
To get the expected multi-line output, you can simply call puts for each line:
puts 'abc'
or
puts 'abc'
puts
or
puts 'abc'
puts
puts
That's just how puts works. It prevents you from needing to append a newline everytime you call puts.
Given no newline, one will be added
Given a trailing newline, an additional one will not be added
Source: http://ruby-doc.org/core-2.4.1/IO.html#method-i-puts

Ruby 1.9 print Array is not Unicode

Why are puts and print results with Unicode characters not the same:
# encoding: utf-8
puts ['裤']
print ['裤']
裤
["\u88E4"]
even though they are the same when they are not in array?
puts '裤'
print '裤'
裤
裤
Is it possible to change print so it always prints Unicode?
I don't see the difference:
puts ['裤']
# 裤
# => nil
print ['裤']
# ["裤"]=> nil
['裤'].inspect
# => "[\"裤\"]"
RUBY_VERSION
# => "1.9.3"
But I think it was because of :print method prints containment of the array without joining its values together, just dump it. I believe that it uses :inspect to print it out. I can't reproduce it, but you try to execute the following ['裤'].inspect on your system.

Why the newline char does not work here?

def say(arg)
"Hello, #{arg}.\n"
end
say("ABC") # => "Hello, ABC.\n"
Why here \n is printed instead of a newline?
because say returns a String. it doesn't print anything.
If you want to print something you should try:
def say(arg)
puts "Hello, #{arg}.\n"
end
You're most likely trying this in irb which displays the Ruby representation of a string. Compare:
irb(main):007:0> puts say("ABC") + say("ABC")
Hello, ABC.
Hello, ABC.
=> nil
irb(main):008:0> puts "ABC" + "ABC"
ABCABC
=> nil
It is actually never printed to stdio or anything like that, you are simply returning a string from a function.
I'll make the assumption that you are evaluating this in IRB, IRB prints out the result of every expression.
use puts or similar.

What is the differences between print and puts in Ruby with example?

May be this is a duplicate question, What is the differences between print and puts in Ruby? Can I have answer with example please?
print does not add a newline at the end.. puts does.
Most other languages have similar structures too.
Java has System.out.println() and System.out.print()
C# has Console.WriteLine() and Console.Write()
Pascal had Writeln() and Write()
It's simple. puts automatically appends a newline when it prints. print prints the string without modification.
Another difference is in the number of underlying write operations. puts is (roughly) equivalent to:
STDOUT.write(str)
STDOUT.write("\n")
And print (roughly) equivalent to:
STDOUT.write(str)
So, in multithreaded environments, puts can create some weird looking stuff, like this:
Message1Messa
ge2
(blank line)
While printing a string with a concatenated newline yields:
Message1
Message2
Other than that, they're the same.
irb(main):014:0> class Person
irb(main):015:1> attr_accessor :name, :age, :gender
irb(main):016:1> end
=> nil
irb(main):017:0> person = Person.new
=> #<Person:0x2bf03e0>
irb(main):018:0> person.name = "Robert"
=> "Robert"
irb(main):019:0> person.age = 52
=> 52
irb(main):020:0> person.gender = "male"
=> "male"
irb(main):021:0> puts person
#<Person:0x2bf03e0>
=> nil
irb(main):022:0> print person
#<Person:0x2bf03e0>=> nil
irb(main):023:0> print person.name
Robert=> nil
irb(main):024:0> puts person.name
Robert
=> nil
The difference between print and puts is that puts automatically moves the output cursor to the next line (that is, it adds a newline character to start a new line unless the string already ends with a newline), whereas print continues printing text onto the same line as the previous time.
puts isn't prefixed by the name of a class or object upon which to complete the method and puts is a method made available from the Kernel module and that is included and searched by default, so usually you won’t need to use Kernel.puts to refer to it.
Kernel.puts "Hello, world!"
puts takes only one argument and is rarely followed by other methods or logic, so parentheses are not strictly necessary.
There are two major differences between puts and print in general.
1. New line
puts take every element and prints in a newline(without specifying the need of a new line character "\n" in the end)
Whereas print doesn't print each element in a new line unless the programmer explicitly specify it.
puts "Hello, Welcome to Ruby"
Output:
Hello, Welcome to Ruby
Dell-System-XPS:~/Documents/2016RoR/Ruby$
print "Hello, Welcome to Ruby"
Output:
Hello, Welcome to RubyDell-System-XPS:~/Documents/2016RoR/Ruby$
Did you notice, there is no new line after the output.
However, the new line should work when you explicitly mention the new line character like below
print "Hello, Welcome to Ruby \n"
Output:
Hello, Welcome to Ruby
Dell-System-XPS:~/Documents/2016RoR/Ruby$
2. Empty characters or NIL values
print statement prints the empty or NIL values but puts statement doesn't print them if they contain NIL values in it.
> print [nil, 33,44,55]
> [nil, 33, 44, 55] => nil
> puts [nil, 33,44,55]
> 33
> 44
> 55
=> nil
"You see the difference, there is no NIL value printed while using puts"
A comparison can be see in print vs put. For example take a look on Input & output in Ruby.

Replacing a %20 with a space in Ruby

I've currently got a string that reads something like ["green%20books"] and I'd like it to read ["green books"].
I thought Googling for this would yield a result pretty quickly but everyone just wants to turn spaces into %20s. Not the other way around.
Any help would be much appreciated!
Edit:
This is the function I'm working with and I'm confused where in here to decode the URL. I tried removing the URI.encode text but that broke the function.
def self.get_search_terms(search_url)
hash = CGI.parse(URI.parse(URI.encode(search_url)).query) #returns a hash
keywords = []
hash.each do |key, value|
if key == "q" || key == "p"
keywords << value
end
end
keywords
end
you can use the 'unencode' method of URI. (aliased as decode)
require 'uri'
URI.decode("green%20books")
# => "green books"
this will not only replaces "%20" with space, but every uri-encoded charcter, which I assume is what you want.
documentation
CGI::unescape will do what you want:
1.9.2-p320 :001 > require 'cgi'
=> true
1.9.2-p320 :002 > s = "green%20books"
=> "green%20books"
1.9.2-p320 :003 > CGI.unescape(s)
=> "green books"
Another option (as YenTheFirst mentioned) might be URI.decode. However, I read a discussion that it would be deprecated -- although that was in 2010.
Anyway, since you're asking about arrays, you would perhaps map using that method:
ary.map { |s| CGI.unescape(s) }
You can use regular expressions:
string = "green%20books"
string.gsub!('%20', ' ')
puts string

Resources