Ruby: method finder gem example - ruby

I found this great gem 'method finder' that I'm trying to use to help improve my understanding of Ruby, problem is that I don't really get it. It gives this example from the docs. The method 'unknown' is supposed to replace whatever method will give the result in the surrounding code, but what is this example telling us?
>> 10.find_method { |n| n.unknown(3) == 1 }
=> ["Fixnum#%", "Fixnum#<=>", "Fixnum#>>", "Fixnum#[]", "Integer#gcd", "Fixnum#modulo", "Numeric#remainder"]

It's telling you exactly what you asked it for: all the methods on 10 that return 1 when passed 3:
>> 10 % 3
=> 1
>> 10 <=> 3
=> 1
>> 10 >> 3
=> 1
>> 10[3]
=> 1
>> …

Related

How to understand objects, methods and arguments in Ruby calculations

While learning Ruby gotchas, I am getting different results with some calculations in IRB:
1-2-7-2 # => -10
1.-2.-7.-2 # => 4
1.-2.-7.-2.-4 # => 8
1.-2.-7.-2.+4 # => 0
1.-(2).-(7).-(2) # => -10
Possibly it is related to methods and arguments? I am trying to wrap my head around this.
You've chosen an interesting way to approach calculations.
I guess you are trying to omit zeros in your expression 1.-2.-7.-2 which will return -10 if you write it as 1.0 - 2.0 - 7.0 - 2.
The way you're getting 4 is because 1.- construction calls -() method because everything is an object in Ruby and then you pass an argument to the function.
In your case it will be parsed as
1.-( 2.-( 7.-(2) ) )
# if we try to unwrap
a = 7.-(2) # => 5
b = 2.-(a) # => -3
1.-(-3) # (or 1 + 3) => 4

Keeping a ruby script running in terminal so I can call different methods

I want to call a ruby script and keep it running while I call methods on it.
I have:
until (a = gets.chomp) =~ /(?:ex|qu)it/i
send(a)
end
This works very well, but I feel like it can't be the best practise?
Can someone reassure me / provide a better solution?
If you want a REPL, you could use IRB or PRY.
Otherwise you could write it yourself :
def handle_input(input)
raise StopIteration if input =~ /^(ex|qu)it$/i
result = eval(input)
puts("=> #{result}")
end
def repl(prompt)
print prompt
handle_input(gets.chomp!)
end
loop do
repl('>> ')
end
Example :
>> 2+3
=> 5
>> "test".size
=> 4
>> 3.times{|i| puts i}
0
1
2
=> 3
>> exit
Using eval usually isn't a good idea. But with your send, you cannot specify a receiver or any parameter.

How to make Lambda (or lambda-like object) to call itself with a new parameter it got (Ruby)

I am within a method and want a simple solution to check client's response.
l=lambda { |answer|
if answer == 1
x*5
elsif answer == 2
x*10
elsif
puts "Please enter 1 or 2"
answer = gets.chomp
l.call(answer)
end
}
Obviously this code doesn't work, since lambda can't "see" itself, but is there a way to achieve the desired effect in a simple-fashioned way?
Because right now I'm just writing a new method to call and passing bunch of parameters, which I wouldn't need to if I were able to check the answers within the current method.
Slightly confused, is this what you're trying to achieve? I notice you have variable x, but this isn't referred anywhere (just answer is).
lam = ->(x) do
x = Integer(x)
case x
when 1
x * 5
when 2
x * 10
else
puts 'Please enter 1 or 2'
input = gets.chomp
lam.call(input)
end
end
# 2.2.2 > lam.call(5)
# Please enter 1 or 2
# 3
# Please enter 1 or 2
# 2
# => 20
# 2.2.2 > lam.call(1)
# => 5

easy and clean puts in ruby

I have very often the situation, that i want to Debug something in Ruby.
Then i have an output to the console with "puts".
Following example:
Testvariable = 4
puts Testvariable
The output is of course:
4
Now i have a lot of outputs and therefore i write very often something like this:
Testvariable = 4
puts "Testvariable= " + Testvariable
The output is then:
Testvariable= 4
Now this was a very easy case but i hope that it shows what my question is.
Does a possibility like this exist???
Testvariable = 4
prettyputs Testvariable
and that the output is directly
Testvariable = 4
I hope you do understand, what my "problem" is? Of course it isnt a lot of work to write the complete string down, but i just want to know if there is a fast and easy possibility?
This is duplicate to: Ruby: getting variable name
In short: you can not get the name of a variable, but you can put a string or a symbol with the name of the variable you want to display
def prettyputs(symb, the_binding)
var_name = symb.to_s
var_value = eval(var_name, the_binding)
puts "#{var_name} = #{var_value.inspect}"
end
toto=1
prettyputs "toto",binding
or
prettyputs :toto,binding
There's a gem called "ap" awesome_print which does more or less what you want.
The case you listed here doesn't really do the question justice, and probably if you are "puts"ing things, you might want to learn more about debugging and testing tools.
From the AP documentation, consider the following:
data = [ false, 42, %w(forty two), { :now => Time.now, :class => Time.now.class, :distance => 42e42 } ]
Printing this with Ruby's builtin puts would be a mess, but AP prints the following:
$ ruby 1.rb
[
[0] false,
[1] 42,
[2] [
[0] "forty",
[1] "two"
],
[3] {
:class => Time < Object,
:now => Fri Apr 02 19:55:53 -0700 2010,
:distance => 4.2e+43
}
]
I realise that's not exactly what you want, but perhaps the following is equally useful:
puts TestVariable.inspect
since you named it uppercase, I'm going to assume it's a class or a constant, and you want to see it's type, which .inspect will do for you.

Ruby Kata Integer conversion troubleshoot [duplicate]

This question already has answers here:
ruby basic data type conversion
(4 answers)
Closed 1 year ago.
I'm solving this ruby kata. Essentially what the code does is to output an integer with five digits.
Example:
5 = 00005
12 = 00012
12345 = 12345
00001234 = 012345
Here is my code:
def solution(value) #00001204
string_value = value.to_s
if string_value.length <= 5
amount_of_zeros = "0" * (string_value.length - 5).abs
puts "Value is #{amount_of_zeros}" + "#{string_value}"
else
start_of_characters = 5 - string_value.length #-3
puts "Value is " + string_value[-1..start_of_characters]
end
end
Everything works fine until I place 00001204. For some reason I get the output 00644. I tried using binding.pry to see what was going on and my number gets converted into 644 from the start. Why is it doing that? The docs don't mention anything about it. I don't how to fix this because on the first line of my method it already turns into 644. Any thoughts?
In ruby, numbers that are 0-prefixed are interpreted as octal. When you pass 00001204 to your method, ruby is assuming that you want the number interpreted as octal. 12048 = 64410.
644.to_s 8
=> "1204"
01204.to_s 10
=> "644"
Check out the Ruby documentation on literals.
as Zajn said it is due to it being interpreted as octal.
You can also use .to_i to force it to be an integer.
>> 000000001204
=> 644
>> "000000001204".to_i
=> 1204
Also take a look at string formatting with % if you just want to output it, since it can clean up your code a lot
>> "%05d" % "000001204".to_i
=> "01204"

Resources