Formatted output in ruby using p function - ruby

How can we obtain formatted output using p function. of ruby.
I need to print a float with exactly two decimal places.
I want to do it using minimum characters so i want to use p function instead of puts and printf.
i have tried this
printf"%.2f",a.abs/2
Any idea on how to reduce characters ?

inspect is the method you need to override for p
class Float
def inspect
sprintf "%.2f", self
end
end
Result
p 12.0
#=> 12.00

Assuming you're ok about a string being returned, you can use use Kernel#sprintf
sprintf "%.2f", 1.234
=> "1.23"
Note that printf is really just sugar for IO.write(sprint()) so the above should be considered equiavelent.

You can use the method String#%
str % arg → new_str
Format—Uses str as a format specification, and returns the result of applying it to arg. If the format specification contains more than one substitution, then arg must be an Array or Hash containing the values to be substituted. See Kernel::sprintf for details of the format string.
In your example:
a = 5.3
p"%.2f"%a
If you use a formula you need additional braces:
p"%.2f"%(a.abs/2)

Related

ruby regex scan and gsub work differently with capture groups in blocks

I have a string of alternating digits and letters. I want to replace each character with the number of letters preceding it. For example, 2a3b should return aabbb.
First, If I do:
"2a3b".scan(/(\d)(.)/) do |count, char|
puts char * count.to_i
end
I get:
aa
bbb
But, if I do:
"2a3b".gsub(/(\d)(.)/) do |count, char|
char * count.to_i
end
I get an error:
NoMethodError: undefined method `*' for nil:NilClass
Shouldn't they both behave the same (Update: I mean, accept capture groups as block params)?
Update : (workaround, which works)
"2a3b".gsub(/(\d)(.)/) do |match|
$2 * $1.to_i
end
returns:
"aabbb"
as expected.
No they don't behave the same.
The block form of gsub only accepts one parameter, so the second is going to be nil, hence your error.
See http://ruby-doc.org/core-2.1.4/String.html#method-i-gsub
Example of use: "hello".gsub(/./) {|s| s.ord.to_s + ' '}
In the block form, the current match string is passed in as a
parameter, and variables such as $1, $2, $`, $&, and $' will be set
appropriately. The value returned by the block will be substituted for
the match on each call.
The result inherits any tainting in the original string or any
supplied replacement string.
No, they are two different methods and do different things.
See http://ruby-doc.org/core-2.2.2/String.html#gsub-method and http://ruby-doc.org/core-2.2.2/String.html#scan-method
In the abstract, scan is more for finding patterns in strings/expressions, (and with a block, formatting them in some way) while gsub is more about doing replacements on patterns in a string.

How to use ":template"-type strings in ruby?

Both rails routes and whenever and a few other things I can't remember have a user-specified template string like so:
template_str = "I am going to :place at :time"
And then there's some magic function which embeds data in place of :place and :time, like so:
template_str.magic_embed_function(place: 'bed', time: '10 pm')
#=> "I am going to bed at 10 pm"
How can I do this in my ruby projects? Is there a gem that implements String#magic_embed_function?
Use Percent-Style Interpolation
There is a special type of interpolation that uses the String#% method. This allows you to interpolate ordinal (Array) and non-ordinal (Hash) inputs into a format string similar to that provided by Kernel#sprintf. However, the use of a hash argument with this method enables support for named variables in the format string. As a minimalist example:
"%{foo} %{bar}" % {foo: 'baz', bar: 'quux'}
#=> "baz quux"
With a hash argument, the format-string placeholders are treated as hash keys to be replaced by the associated values in your hash. This makes the order of the variables passed in unimportant. Based on the code in your original post, you could use it as follows:
template_str = 'I am going to %{place} at %{time}.'
template_str % {time: '10:00 PM', place: 'bed'}
#=> "I am going to bed at 10:00 PM."
This is a useful technique when you want to pass an array or hash for interpolation, but may or may not offer advantages over other types of interpolation in the general case. Your mileage may vary.
I extended String class with a magic_embed_function as you asked..rs
It's very simple, first we split our string and collect the words and check if matches with this simple regex for symbols, basically says "if something starts with : , that's a symbol", after we found a symbol we replace using gsub! (global substitution, with the bang to change our object) passing our symbol as first param and the param received that corresponds to that symbol and at the end we return self, to return the string that called the method.
template_str = "I am goind to :place at :time"
class String
def magic_embed_function(params)
self.split(" ").collect do |value|
if value =~ /:.*/
self.gsub! value, params[value[1..value.length].to_sym]
end
end
self
end
end
p template_str.magic_embed_function({place: "bed", time: "10 pm"})
#"I am goind to bed at 10 pm"

How to obtain the binary literal from a integer in Ruby?

I would like to get the binary literal corresponding from a given integer, in this way:
4.to_literal
=> 0b100
Is there such to_literal method?
Use to_s with its optional base parameter to get a string.
4.to_s(2) #=> "100"
You can't get a literal as output.
Use String#% or Kernel#sprintf (%#b as format specifier):
'%#b' % 4
# => "0b100"
sprintf('%#b', 4)
# => "0b100"

How to validate that a string is a proper hexadecimal value in Ruby?

I am writing a 6502 assembler in Ruby. I am looking for a way to validate hexadecimal operands in string form. I understand that the String object provides a "hex" method to return a number, but here's a problem I run into:
"0A".hex #=> 10 - a valid hexadecimal value
"0Z".hex #=> 0 - invalid, produces a zero
"asfd".hex #=> 10 - Why 10? I guess it reads 'a' first and stops at 's'?
You will get some odd results by typing in a bunch of gibberish. What I need is a way to first verify that the value is a legit hex string.
I was playing around with regular expressions, and realized I can do this:
true if "0A" =~ /[A-Fa-f0-9]/
#=> true
true if "0Z" =~ /[A-Fa-f0-9]/
#=> true <-- PROBLEM
I'm not sure how to address this issue. I need to be able to verify that letters are only A-F and that if it is just numbers that is ok too.
I'm hoping to avoid spaghetti code, riddled with "if" statements. I am hoping that someone could provide a "one-liner" or some form of elegent code.
Thanks!
!str[/\H/] will look for invalid hex values.
String#hex does not interpret the whole string as hex, it extracts from the beginning of the string up to as far as it can be interpreted as hex. With "0Z", the "0" is valid hex, so it interpreted that part. With "asfd", the "a" is valid hex, so it interpreted that part.
One method:
str.to_i(16).to_s(16) == str.downcase
Another:
str =~ /\A[a-f0-9]+\Z/i # or simply /\A\h+\Z/ (see hirolau's answer)
About your regex, you have to use anchors (\A for begin of string and \Z for end of string) to say that you want the full string to match. Also, the + repeats the match for one or more characters.
Note that you could use ^ (begin of line) and $ (end of line), but this would allow strings like "something\n0A" to pass.
This is an old question, but I just had the issue myself. I opted for this in my code:
str =~ /^\h+$/
It has the added benefit of returning nil if str is nil.
Since Ruby has literal hex built-in, you can eval the string and rescue the SyntaxError
eval "0xA" => 10
eval "0xZ" => SyntaxError
You can use this on a method like
def is_hex?(str)
begin
eval("0x#{str}")
true
rescue SyntaxError
false
end
end
is_hex?('0A') => true
is_hex?('0Z') => false
Of course since you are using eval, make sure you are sending only safe values to the methods

Ruby global match regexp?

In other languages, in RegExp you can use /.../g for a global match.
However, in Ruby:
"hello hello".match /(hello)/
Only captures one hello.
How do I capture all hellos?
You can use the scan method. The scan method will either give you an array of all the matches or, if you pass it a block, pass each match to the block.
"hello1 hello2".scan(/(hello\d+)/) # => [["hello1"], ["hello2"]]
"hello1 hello2".scan(/(hello\d+)/).each do|m|
puts m
end
I've written about this method, you can read about it here near the end of the article.
Here's a tip for anyone looking for a way to replace all regex matches with something else.
Rather than the //g flag and one substitution method like many other languages, Ruby uses two different methods instead.
# .sub — Replace the first
"ABABA".sub(/B/, '') # AABA
# .gsub — Replace all
"ABABA".gsub(/B/, '') # AAA
use String#scan. It will return an array of each match, or you can pass a block and it will be called with each match.
All the details at http://ruby-doc.org/core/classes/String.html#M000812

Resources