From: Max Schmidt Date: 2010-03-31T18:55:36+09:00 Subject: Re: RubyDictionary - First Try Hello and thank you for this fast widespread answer! >Your implementation allows to insert two pairs with the same key This totally was my intention, because one word can be translated in many different ways. Associative Arrays are called "Hashs" in Ruby, aren't they? 1 - >def initialize(entries=nil) > @entries = entries || [] # or Array.new if you prefer >end Nice idea, I never would consider a boolean operator as a expression, which returns anything else than "true" or "false" 2 - >def []=(word1, word2) Don't you think that this definition is rather confusing, if Dictionary is NOT an associative array? I have to admit that I am still not familiarized with these method-like operators... 3 - >Why don't you allow one letter words? Because strings with one letter aren't any words, they are characters. My aim was to develop a dictionary where you can organize "real-life" words >if the string doesn't match you get a >irb(main):160:0> d.insert_words "a", "b" >NoMethodError: undefined method `[]' for nil:NilClass > from (irb):94:in `is_word?' Ok, fixed it like this: >match = word.match(/[a-zA-Z]{2,15}/); >if (match!=nil && match[0].length == word.length) then true >def self.is_word? word > word.match(/\A[:alpha:][:alpha:]+\z/) #you can remove the first >[:alpha:] to allow 1-letter words >end I wanted to limit the word's length to 15 as you can see in my regular expression. Are the "\A" (start position) and "\z" (end position) necessary? 4 - >Another way, not necesarily better: > def insert_dict_entry(entry) > @entries << entry.dup > end I should have written the question more accurate. The problem was to check the entry for compability by invoking insert_words() before appending to @entries I considered making a special function for that, like "is_insertable?", but I was still unsure about that 5 - > this way, even if the arrays have different size, you store as much as > you can. If you still want the check you can add it. Hmm, I want the length-check remain. > def insert_array(words1, words2) > words1.zip(words2).each {|first,second| insert_words(first,second) > if first && second} > end Why do you prefer to a implementation which produces a temporaly array? 6 - 7 - > This one doesn't make sense for the public interface of a dictionary. > If you implement remove as above, you don't need it anymore. This was meant to be a time-saver. You can output the Dictionary by typing "o/output", find the index of the entry you want to delete and then apply it to the "r/remove" - command 8 - Very cool! 9 - > Why do you need the index as a return value? for "remove" - I first searched for the word pair and if found I removed the pair by calling remove_at(found_index) > @entries.find {|entry| entry == [word1,word2]} I slowly realize that I will have to clearly go through the Array methods this afternoon. 10 - >@entries.each_with_index {|entry, i| s << sprintf("%3d %15s | > %15s\n", i, entry.word1 , entry.word2) This means it is actually never recommended to use >@entries.length.times {|i| ... } to iterate through an array? DictionaryEntry 11 - > you might want to dup the words to avoid aliasing Do you mean to avoid exceptions when the words are frozen? If yes, I would throw an Exception if either of the two words is frozen. 12 - >Enumerable doesn't provide the method [] Ok, I was convinced that Enumerables behave like Arrays >I'm not sure you want to keep the equality comparison with an >Enumerable ... then I should replace the Enumberable with i.e. an Array like this? >case other > when Array > @word1 == other[0] && @word2 == other[1] > when DictionaryEntry > @word1 == other.word1 && @word2 == other.word2 > else > false >end Again, thanks for your effort -- Posted via http://www.ruby-forum.com/.