I found this weirdness that I would like to understand. If I define these two methods in pry...
def test(*args)
puts args
end
def test=(*args)
puts args
end
they both work.But if I put the above code in a module and include that module in another class (say, class Job), the following
j=Job.last
j.test=(1,2,3)
throws the following error...
SyntaxError: (irb):3: syntax error, unexpected ',', expecting ')'
j.test=(1,2,3)
^
The following work as expected...
j.test=[1,2,3]
j.test=(1)
So, it looks like inside the module, a method defined with an '=' always expects one arg. That doesn't make sense to me.
What am I missing
Parsing of the Ruby interpreter. Try
j.send :test=, 1, 2, 3
use directly
j.test = 1,2,3
or
j.test= ([1,2,3])
or `
j.send('test=',[1,2,3])
Related
I am trying to declare a class with a few basic functions in it. The function that seems to be causing a problem has an optional argument that passes a symbol in.
class Bag < RandomizerCollection
def initialize()
end
def select(description:Hash, amt=:all)
end
def empty()
end
end
And the error I am getting is:
Traceback (most recent call last):
1: from test.rb:5:in `<main>'
test.rb:5:in `require_relative': /home/osboxes/Documents/Year4/Design/A1/Bag.rb:9: syntax error, unexpected tIDENTIFIER (SyntaxError)
...ef select(description:hash, amt = :all)
... ^~~
/home/osboxes/Documents/Year4/Design/A1/Bag.rb:9: syntax error, unexpected ')', expecting keyword_end
...t(description:hash, amt = :all)
I'm sure this must be something basic but I just can't figure it out. I am new to Ruby and I found similar questions but none helped me find the issue. Any help is appreciated!
You can't define optional arguments (arg=value) after the definition of the keyword arguments (arg: value).
You can correct it in two ways:
Move optional arg before the keywor arg:
def select(amt=:all, description:Hash)
end
Make the second argument a keyword arg:
def select(description:Hash, amt: :all)
end
Worth reading: https://medium.com/podiihq/ruby-parameters-c178fdcd1f4e
I have the below code under test:
class MethodCache
##methods=Hash.new
def self.add_method(name, &block)
##methods[name]=block
end
def self.get_method(name)
##methods[name]
end
end
Now my spec looks like this:
describe MethodCache do
subject {MethodCache}
foo_block = ->{ puts "foo"}
it ".get_method" do
subject.add_method "foo", &foo_block
# does not work
# expect(subject.get_method("foo").to be &foo_block
# should syntax works
subject.get_method("foo").should be foo_block
end
end
I am trying to stay away from should syntax and use the expect syntax of RSpec. However it does not work in this case.
expect(subject.get_method("foo").to be &foo_block fails saying wrong number of arguments. I guess this is because the expectation block is treated as a block argument.
expect(subject.get_method("foo").to be foo_block (without the '&') does not work either. It says, the matcher expects a value and not argument.
What am I missing here?
I am getting the following error in Ruby Koans:
AboutHashes#test_accessing_hashes_with_fetch has damaged your karma.
The Master says:
You have not yet reached enlightenment.
I sense frustration. Do not be afraid to ask for help.
The answers you seek...
class or module required
Please meditate on the following code:
/home/s/Downloads/github/rubykoans/about_hashes.rb:26:in `test_accessing_hashes_with_fetch'
The line in question is part of the following method:
def test_accessing_hashes_with_fetch
hash = { :one => "uno" }
assert_equal "uno", hash.fetch(:one)
assert_raise(nil) do
hash.fetch(:doesnt_exist)
end
As you can see, it is asking for a class or module, so I am confused as this is not an error I've encountered before in the Koans.
The problem is on these lines:
assert_raise(nil) do
hash.fetch(:doesnt_exist)
end
The assert_raise test macro expects as its argument a class of Exception. You provided nil.
To skip to the answer, calling fetch on a hash with a key that doesn't exist in the hash will raise a KeyError Exception. So the test should have this:
assert_raise(KeyError) do
hash.fetch(:doesnt_exist)
end
The error is:
C:/Users/Admin/Desktop/MyFirstSelfMadeGame.rb:18: syntax error, unexpected keyword_end, expecting $end
Code:
#!/usr/bin/env ruby
require "gosu"
class GameWindow < Gosu::Window
def initialize(800, 600, false) #Window declaration
super
self.caption("Pokemon")
end
def update
end
def draw
end
def button_down(id)
close if id == Gosu::KbSpace
end
end
GameWindow.new.show
Thanks for answers, i get this problem alot.
No, this is not the whole error, the whole error looks something like:
t.rb:6: syntax error, unexpected tINTEGER, expecting ')'
def initialize(800, 600, false) #Window declaration
^
t.rb:21: syntax error, unexpected kEND, expecting $end
Please note that there are 2 error messages reported by the Ruby interpreter. You have noticed and posted only the 2nd one, but the 1st one is actually the relevant one. In general, if you receive error messages, it's a good rule of thumb to find and fix the 1st one first, because the subsequent ones may be caused by the first one.
You need to specify for function arguments. Incorrect:
def initialize(800, 600, false) #Window declaration
Correct:
def initialize()
super(800, 600, false)
As pts says, you cannot reference objects in a method definition arguments
The method definition arguments should only contain variables that you reference in the method.
If you want to use defaults but have the option to override the arguments when calling the 'new' method you could do...
def initialize(width=800, height=600, full_screen=false)
super(width, height, full_screen)
Also, you should note that self.caption is a getter method and doesn't take arguments
this is wrong
self.caption("Pokemon") # < wrong
this is right
self.caption = "Pokemon" # < right
Take a look at the tutorial game...
https://github.com/jlnr/gosu/wiki/Ruby-Tutorial
I am working on a RoR project, and I want to know if I can use end as a method name. It seems to work fine, but I would like to know if this method will bring any issues in the future. I tried and it works:
class Dany
def end
puts 'Hola'
end
end
and this is the output:
Dany.new.end # => Hola
Ruby let's you do this, but you're going to run into all sorts of issues.
# end.rb
class Dany
def end
puts "Hola"
end
def other
end # should puts Hola
end
end
Instead, you will get
end.rb:10: syntax error, unexpected keyword_end, expecting end-of-input
Bottom line: don't do this. Don't use any keywords as a method name.
It is not a good idea to use a keyword as a method name, but as long as you disambiguate the token as a method call, you can use it. It is not practical though.
Dany.new.instance_eval{self.end} # => Hola
Dany.new.send(:end) # => Hola
Dany.new.method(:end).call # => Hola
Dany.new.instance_eval{end} # => syntax error, unexpected keyword_end
The usual disambiguation using () does not seem to work for this case, making it complicated.
Dany.new.instance_eval{end()} # => syntax error, unexpected keyword_end