Within a method, I want to dynamically evaluate the following code chunk with a regex:
if (/^[A-F][A-Z]*[^\.\*]$/).match(some_value)
The method I attempted is this:
def check(val)
if (/^[val][A-Z]*[^\.\*]$/).match(some_value)
puts "foo"
else
puts "waa"
end
end
check("A-F")
The value I am passing in is not making it there correctly. It appears that passing a value in this fashion needs something more. Is this not something you can do with a method?
You expected string interpolation. To do that, you need to use the interpolation syntax #{}:
def check(val)
if (/^[#{val}][A-Z]*[^\.\*]$/).match(some_value)
puts "foo"
else
puts "waa"
end
end
Related
I am working on the following problem:
describe "some silly block functions" do
describe "reverser" do
it "reverses the string returned by the default block" do
result = reverser do
"hello"
end
expect(result).to eq("olleh")
end
From my understanding this should reverse a string. My code is as follows:
def reverser
yield "hello"
end
reverser do |i|
puts i.reverse
end
This simply returns "hello". I may be missing some fundamental concepts here about how yield, blocks, and functions all interact. How do I going about doing what I am trying to accomplish?
The answers are good and correct but perhaps it still do not help.
You should start with your spec:
it "reverses the string returned by the default block"
So, it's very clear what your method should do:
def reverser
# should reverse the string returned by the default block
end
Let's now see how to achieve it. Ok, it should reverse something. But what? Let's see:
string returned by the default block
This suggests that we need to execute the default block and get its returned value. Let's see what the docs say:
yield - Called from inside a method body, yields control to the code block (if any) supplied as part of the method call. ... The value of a call to yield is the value of the executed code block.
So, it seems that your method needs to perform a yield. It will execute a block and return the value the block returns. So, just put a yield there.
def reverser
yield
end
If you run your spec, it will complain - you will see that the string is still not reversed. So, that's whats left for your method to do:
def reverser
yield.reverse
end
and that's it.
You need to include the logic of reversing the string in reverser.
def reverser
yield.reverse
end
But why bothering using block anyway? It's much clearer to use a normal parameter.
def reverser(str)
str.reverse
end
reverser('hello') #=> olleh
If you want to put the string to reverse in the block, then you need to get the result of calling the block and reverse it.
def reverser(&block)
block.call.reverse
end
irb(main):009:0> result = reverser do
irb(main):010:1* "hello"
irb(main):011:1> end
=> "olleh"
I know it's been a year but this hasn't been answered right.
def reverser
out = []
yield.split.each{|word| out << word.reverse}
out.join(" ")
end
I'm pretty sure it has to do with scope
I agree with the above responses - they make the most sense. but want to add why your code isn't working and how to fix it:
expect(result).to eq("olleh")
So according to that you want result to return a string. Is it doing that?
puts returns nil. when you have puts at the end of a method - be aware that the method will return nil. It's insidious because sometimes the results are not what is expected.
but you are expecting it to return 'olleh'
get rid of the puts and it should work like you expect (untested)
def reverser
yield "hello"
end
reverser do |i|
i.reverse # NOTE THAT THE PUTS is missing here
end
I think that's what you are looking for.
edit: Please test and let me know because some folks think I have the answer completely wrong! of course you'd not want to rely on the particular block that you are using as a design point, but this should give you an idea of why it wasn't working
Could someone give me an example of a method that accepts a single string argument. Whilst i appreciate this might seem trivial I am trying to understand how this works in ruby. Would the syntax below be correct.
Def method("argument")
true
end
You need to check if it is a string by yourself. You can make use of is_a? to see if it is a String as Ruby is dynamically typed.
def add_watson(f_name)
f_name << " Watson" if f_name.is_a? String
end
Now, calling it
puts add_watson("Emma") #=> Emma Watson
No, it wouldn't. First of all, def keyword is lowercased. Also, method argument(s) is written like this def my_method(argument) and at this point it doesn't check if it's string, in fact, it can accept any object, because Ruby is typed dynamically. If you want to force String instance as an argument, you can do it inside of method body:
def my_method(argument)
raise ArgumentError, "argument must be a String" unless argument.is_a? String
true
end
Your syntax is wrong.
def method(arg)
puts "arg"
end
You can review some tutorial too
http://www.tutorialspoint.com/ruby/ruby_methods.htm
http://www.skorks.com/2009/08/method-arguments-in-ruby/
Can't figure out what code to put in "05_silly_blocks" to call the string from the block reverser that is stored in the variable result.
require "05_silly_blocks"
describe "some silly block functions" do
describe "reverser" do
it "reverses the string returned by the default block" do
result = reverser do
"hello"
end
result.should == "olleh"
end
Also does it make a difference is the block is not stored in a variable like result?
I'm not sure I exactly understand what you are trying to accomplish with the blocks, but if you want to reverse a String in Ruby you can just say "hello".reverse.
The reverser method would look something like this:
def reverser
yield.reverse
end
This is a dangerous implementation however, as it assumes that whatever is passed to the block will return a String at the very end.
I'm working on some homework problems for a ruby course and I've been having some trouble with my answer. Basically I need to build a program that can satisfy these conditions:
describe "reverser" do
it "reverses the string returned by the default block" do
result = reverser do
"hello"
end
result.should == "olleh"
end
it "reverses each word in the string returned by the default block" do
result = reverser do
"hello dolly"
end
result.should == "olleh yllod"
end
end
I puzzled together some code that I feel should satisfy these conditions:
reverser = Proc.new do |string|
words = string.split(/\b/)
answer = ''
i = 0
while i < words.count
answer = answer + words[i].reverse
i += 1
end
answer
end
def reverser
yield
end
Yet when I run the rake, my error tells me I have failed the first condition.
expected: "olleh"
got: "hello"
Is there something I'm missing? Do I just not have a proper understanding of procs?
This question has been asked in some form already by a member named pete and answered quite well by another user named mind.blank. This is the source:
Beginner RSpec: Need help writing Ruby code to pass RSpec tests (Silly Blocks exercise).
mind.blank's code was straightforward and worked properly, but I don't just want to copy it without understanding why mine doesn't work. Thanks in advance for any help.
So - what you've got there is a local variable named "reverser" and a method named "reverser" (which is going to "shadow" the reverser local)
Your code is never executing.
So - what you want to do is ... take the result of the yield and do the reverse operation on that. (Leaving aside how bizarre that requirement is for a moment.)
def reverser
string = yield
# ... all of your reverser code ...
end
Now circling back around - that's a bizarre way to use a block. A block is for passing additional execution to a method, not for passing argument to it. So if you wanted to say, have a callback executed for each character in reverser (in reverse?) that would be the proper use of yield.
Besides, Ruby already has a String#reverse method - so the easiest possible thing to do to get your tests to pass is something like.
def reverser
(yield).split(/\b/).map(&:reverse).join
end
Your reverser proc does work, if you say reverser.call('abc') (or reverser['abc'] or reverser.('abc')) then you will get the expected 'cba' back.
The problem is that your test isn't using your reverser proc, it is using your reverser method. This is a call to the reverser method with a block:
result = reverser do
"hello"
end
but the reverser method doesn't do anything interesting, it just yields to the block:
def reverser
yield
end
so result ends up being the block's value and that's 'hello'.
Either test the proc:
it "reverses the string returned by the default block" do
result = reverser['hello']
result.should == "olleh"
end
or move the proc's guts into the reverser method and test that:
def reverser
string = yield
words = string.split(/\b/)
answer = ''
i = 0
while i < words.count
answer = answer + words[i].reverse
i += 1
end
answer
end
There are better ways to write this code (such as words.map(&:reverse).join instead of the while look) but your reversing logic works, you just have to make sure you call the right version.
This code will reverse strings given to the method as a block
def reverser
# yield is the string given in the block
words = yield.split(' ')
final = []
words.each do |word|
final.push(word.reverse)
end
final.join(' ')
end
Neither to_s nor to_str appear to get called when an object is referenced inside a double-quoted string interpolation. For example:
# UPDATE: This example actually works as expected. See update below.
class Foo
def to_s
'foo'
end
def to_str
to_s
end
end
"#{Foo.new}" # result: "#<Foo:0x007fb115c512a0>"
I don't suppose there's something I can do to make the return value "foo"?
UPDATE
Apologies, but this code actually works. Mistake in another piece of code.
With what version of Ruby are you seeing these results? This works correctly for me with Ruby 1.9.2 and 1.8.6:
class Foo
def to_s
'hi mom'
end
end
puts "#{Foo.new}"
#=> hi mom
You're not returning a string. Remove the puts, since to_s needs to RETURN a string representation, not output it.
Note: this response is based on a previous version of the question where the to_s method had the code puts "foo".