I got this error in RSpec. Are there any docs for have_selector that explain each key in the options hash and what exactly it does?
invalid keys :content, should be one of :text, :visible, :between, :count, :maximum, :minimum, :exact, :match, :wait
capybara provides this method to rspec. capybara's docs don't make it easy to find the answer to your question, so let's follow the source:
have_selector is in Capybara::RSpecMatchers. It delegates to the nested class HaveSelector, which delegates to the method assert_selector.
assert_selector is in Capybara::Node::Matchers. (So is a method has_selector?, although that's not what rspec calls.) assert_selector's rdoc documents the :count option. It also says "It also accepts all options that Finders#all accepts, such as :text and :visible." Clicking through to Finders#all finally gets us to the documentation of all the options:
Options Hash (options):
text (String, Regexp) — Only find elements which contain this text or match this regexp
visible (Boolean) — Only find elements that are visible on the page. Setting this to false finds - invisible and visible elements.
count (Integer) — Exact number of matches that are expected to be found
maximum (Integer) — Maximum number of matches that are expected to be found
minimum (Integer) — Minimum number of matches that are expected to be found
between (Range) — Number of matches found must be within the given range
exact (Boolean) — Control whether is expressions in the given XPath match exactly or partially
Related
In Ruby, the to_s on an object includes an encoding of the object's id.
[2] pry(main)> shape = Shape.new(4,4)
=> #<Shape:0x00007fac5eb6afc8 #num_sides=4, #side_length=4>
In the documentation it says
Returns a string representing obj. The default to_s prints the object’s class and an encoding of the object id.
https://apidock.com/ruby/Object/to_s
In the example above, the encoding of the object id is 0x00007fac5eb6afc8.
In How does object_id assignment work? they explain
In MRI the object_id of an object is the same as the VALUE that represents the object on the C level.
So I compared to the object_id and it is not the same as the encoding of the object id.
[2] pry(main)> shape = Shape.new(4,4)
=> #<Shape:0x00007fac5eb6afc8 #num_sides=4, #side_length=4>
[3] pry(main)> shape.object_id
=> 70189150066660
What exactly is the encoding of the object id? It does not appear to be the object_id.
Think of the object_id, or __id__ as the "pointer" for the object. It is not technically a pointer, but does contain a unique value that can be used to retrieve the internal C VALUE.
There are patterns to the value it has for some data types, as you can see with its hexadecimal representation with to_s. I am will not go into all the details, as there are already numerous answers on SO explaining, and already linked from comments, but integers (up to a FIXNUM_MAX, have predictable values, and special constants like true, false, and nil will always have the same object_id in every run.
To put simply, it is nothing more than a number, and shown as a hexadecimal (base 16) value, not any actual "encoding" or cypher.
Going to expand upon this a bit more in light of your latest edits to the question. As you posted, the hexadecimal number you see in to_s is the value of the internal C VALUE of the object. VALUE is a C data type (unsigned, pointer size number) that every Ruby object is represented as in C code. As #Stefan pointed out in a comment, for non-integer types (I speak only for MRI version), it is twice the value of the object_id. Not that you probably care, but you can shift the bits of an integer to predict the value for those.
Therefore, using you example.
A value of 0x00007fac5eb6afc8 is simple hexadecimal notation for a number. It uses a base 16 counting system as opposed to the base 10 decimal system we are more used to in everyday life. It is simply a different way of looking at the same number.
So, using that logic.
a = 0x00007fac5eb6afc8
#=> 140378300133320 # Decimal representation
a /= 2 # Remember, non-integers are half of this value
#=> 70189150066660 # Your object_id
The best answer you can get is: You don't know, and you shouldn't need to.
Ruby guarantees exactly three things about object IDs:
An object has the same ID during its lifetime.
No two objects have the same ID at the same time.
IDs are integers.
In particular, this means that you cannot rely on a specific object having a specific ID (for example, nil having ID 8). It also means that IDs can be re-used. You should think of it as nothing but opaque identifier.
And, as you quoted, the default Object#to_s uses "some" encoding of the ID.
And that is all you know, and all you should ever rely on. In particular, you should never try to parse IDs or Object#to_s.
So, the ID part of Object#to_s is "some unspecified encoding" of the ID, which itself is "some opaque identifier".
Everything else is deliberately left unspecified, so that different implementations can make different choices that make sense for their specific needs. For example, it would be stupid to tie object IDs to memory addresses, because implementations like JRuby, Opal, IronPython, MagLev, and Topaz run on platforms where the concept of "memory address" doesn't even exist! And Rubinius uses a moving garbage collector, where objects can move around in memory and thus their address changes.
How to use an argument with question mark in methods have keyword arguments?
def foo(arg?:)
p arg? # ERROR
end
foo(arg?: true)
You can't do that. Parameter names can't have question or exclamation marks. Only method names can have them.
As John mentions, you should be able to use the good old options hash. Although, in this case foo(arg?: true), arg?: true is a key-value pair in a hash, not a keyword argument. Big difference (with options hash, you don't get effortless required parameters and typo protection, for example).
Update
Just confirmed it, you can do foo(arg?: true)
Original:
I'm not sure that you can have a "?" in a kwarg. You could try making the method have one input arg which is a hash, and then I think you could do
def foo(arg)
p arg[:"arg?"]
end
foo(:"arg?" => true)
The quotes may not be necessary, I'd have to open up the console to check. In which case:
foo(arg?: true)
Update 2
Sergio has rightly called out the fact that I'm not using a key word argument (kwarg) in this solution, instead I'm passing a single, regular argument which I know needs to be a hash with a :arg? key. This is commonly referred to as an options hash. This is what people did before the ruby language added support for kwargs (or so I'm told :).
In the official YARD docs, there is the following example:
# #overload set(key, value)
# Sets a value on key
# #param key [Symbol] describe key param
# #param value [Object] describe value param
# #overload set(value)
# Sets a value on the default key +:foo+
# #param value [Object] describe value param
def set(*args) end
What special meaning does +:foo+ have when it is wrapped with + on either side? Does +:foo+ have a different meaning from :foo?
It has no meaning to YARD. In fact, YARD doesn't care about markup at all, it simply passes the string through to the output generator tool unprocessed. (With some limited exceptions, e.g. support for references to modules, classes, methods.)
It does, however, have meaning to SimpleMarkup / RDoc (which is one of the output processors YARD supports). +foo+ is RDoc's syntax for code highlighting, i.e. it is equivalent to `foo` in Markdown.
So the difference is that :foo is rendered as ":foo" whereas +:foo+ is rendered as ":foo", assuming that you use SimpleMarkup / RDoc as the output processor. If you use Markdown as the output processor, it doesn't mean anything at all.
I checked using File.open('file.txt').class and File.open('file.txt').readlines.class and the former one returns File and the latter returns Array.
I understand this difference, but if I do something like:
File.open('file.txt').collect {|l| l.upcase}
=== File.open('file.txt').readlines.collect {|l| l.upcase}
it returns true. So are there any differences between the two objects when each item in the object is being passed to a block as an argument?
And also, I was assuming that the arguments that are passed to the block in both expressions are both a line in the file as a string which makes the comparison return true, is that correct? If so, how do I know what kind of argument will be passed to the block when I write the code? Do I have to check something like the documentation or the source code?
For example, I know how
['a','b','c'].each_with_index { |num, index| puts "#{index + 1}: #{num}" }
works and take this for granted. But how do I know the first argument should be each item in the array and the second the index, instead of the reverse?
Hope that makes sense, thanks!
Get comfortable doing some Ruby introspection in irb.
irb(main):001:0> puts File.ancestors.inspect
[File, IO, File::Constants, Enumerable, Object, Kernel, BasicObject]
This result shows us classes the File class inherits from and that includes the methods of class Enumerable. So what object is returned from File.readlines? An Array I think, let's check.
ri File.readlines
IO.readlines(name, sep=$/ [, open_args]) -> array
IO.readlines(name, limit [, open_args]) -> array
IO.readlines(name, sep, limit [, open_args]) -> array
This may be overkill, but we can verify Enumerable methods exists within an Array.
irb(main):003:0> puts Array.ancestors.inspect
[Array, Enumerable, Object, Kernel, BasicObject]
I'll try to make this response as compact as possible.
The second question - if you operate on objects which come from standard library you may always refer to their documentation in order to be 100% sure what arguments to expect when passing a block. For instance, multiple times you will be using methods like each, select, map (etc ...), on different data structures (Array, Hash, ...). Before you get used to them you may find all information about them in docs for example: http://ruby-doc.org/core-2.2.0/Array.html
If you are operating on non core data structures (for example a class which comes from gem you include, you should always browse it's documentation or sources on Github).
The first question. Result may be the same, when using different methods, but on deeper level there may be some differences. As far as your case is based on files. Reading file content may be processed in two ways. First - read everything into memory and operate on array of string, and the second - read file lines sequentially which may last longer but will not reserve as much memory.
In Enumerable#each_with_index the arguments are in the same order as they are in the method name itself, first the element, then the index. Same thing with each_with_object.
I'm fairly new to ruby. Recently, I wanted to extract a portion of a string from the n'th character of said string to the end.
Doing something like s[n,(s.size - n)] seemed pretty inelegant to me, so I asked a couple of friends.
One suggested I try s[n..-1], and sure enough that works, but he couldn't give me a good reason why it should work. I find the fact that it works rather puzzling, as the following output from irb1.9 should explain:
> s = "0123456789"
=> "0123456789"
> s[2..-1]
=> "23456789"
> (2..-1).to_a
=> []
So as you can see, the range object 2..-1 is empty -- it has no members, which is absolutely what you expect if you go upwards in value from 2 to -1. This is consistent with the documentation for how range objects should work.
The documentation for indexing a string with a range clearly says: "If given a range, a substring containing characters at offsets given by the range is returned" -- but that is an empty set.
I also can find no examples in "The Ruby Programming Language" or in the Ruby docs in which a string is indexed using s[n..-1] or the like, and can find no examples of it in other official sources. It appears to be folklore, however, that it works even though nothing in the manuals indicate that you can index a string with a range this way, and get the result you get even though the range has no members.
Yet, my friend was correct, it works.
So, could someone please explain why this works to me? I'm also very much interested in knowing if the fact that it works is a fluke of MRI/YARV or if this is absolutely expected to work in all Ruby implementations, and if so, where is it documented to work?
EDITED TO ADD:
An answerer below claimed that only the range's begin and end attributes matter for these purposes, but I can find no documentation of that in TRPL or in the Ruby documentation. The answer also claims that there are indeed examples of such "mixed-sign" range indexing, but the only one I could find was in a context where the mixed-range index was shown to produce nil, not a slice of a string. I therefore don't find that answer satisfying.
EDITED TO ADD:
It appears that the correct answer is that this is indeed a defect in the Ruby documentation.
EDITED TO ADD:
The bug was fixed by the Ruby documentation team: see https://bugs.ruby-lang.org/issues/6106
This is a bug in the documentation.
Ruby's documentation has sucked since the Pickaxe book descended like a meteor on matz's actually correct and comprehensive HTML doc. This is a subject that still irritates me on occasion. The answer to your question, from 1.4: link
self[nth]
Retrieves the nth item from an array. Index starts from zero. If index is the negative, counts backward from the end of the array. The index of the last element is -1. Returns nil, if the nth element is not exist in the array.
self[start..end]
Returns an array containing the objects from start to end, including both ends. If ... is used (instead of ..), then end is not included. if end is larger than the length of the array, it will be rounded to the length. If start is out of an array range , returns nil. And if start is larger than end with in array range, returns empty array ([]).
-1 is the last index of an array by definition, as a convenience.
You're right that the range n..-1 is empty. However that doesn't matter because String#[] doesn't treat the range as a collection - it just uses the range's begin and end attributes.
Regarding documentation: The rdoc documentation of String#[] lists the behavior of String#[] for every possible type of argument (including ranges with negative numbers) with examples. So you don't have to rely on folklore. Relevant quote:
If given a range, a substring containing characters at offsets given by the range is returned. [...] if an offset is negative, it is counted from the end of str.
[...]
a = "hello there"
# ...
a[-4..-2] #=> "her"