Как работи методът на дефиниране на [квадратна скоба] в Ruby?

Translate

ПреживявамПрограмиране на Ruby - прагматично ръководство за програмистии са се натъкнали на тази част от кода:

class SongList
  def [](key)
    if key.kind_of?(Integer)
      return @songs[key]
    else
      for i in [email protected]
        return @songs[i] if key == @songs[i].name
      end
    end
    return nil
  end
end

Не разбирам как работи методът за дефиниране []?

Защо ключът е извън [], но когато методът е извикан, той е вътре []?

Може ли ключът да е без скоби?

Осъзнавам, че има много по-добри начини да напиша това и знам как да напиша свой собствен метод, който работи, но този [] метод просто ме озадачава ... Всяка помощ е много благодарна, благодаря

This question and all comments follow the "Attribution Required."

Всички отговори

Translate

Методите в рубин, за разлика от много езици, могат да съдържат някои специални знаци. Един от тях е синтаксисът за търсене на масив.

Ако трябваше да внедрите свой собствен хеш клас, при който при извличане на елемент във вашия хеш искате да го обърнете, можете да направите следното:

class SillyHash < Hash

  def [](key)
    super.reverse
  end

end

Можете да докажете това, като извикате хеш със следното:

a = {:foo => "bar"}
 => {:foo=>"bar"} 
a.[](:foo)
 => "bar" 
a.send(:[], :foo)
 => "bar" 

Така че def [] определи метода, който се използва, когато го направитеmy_array["key"]Други методи, които може да ви изглеждат странни, са:

class SillyHash < Hash

  def [](key)
    super.reverse
  end

  def []=(key, value)
    #do something
  end

  def some_value=(value)
    #do something
  end

  def is_valid?(value)
    #some boolean expression
  end

end

Само за да изясня, дефиницията на a[]метод не е свързан с масиви или хешове. Вземете следния (измислен) пример:

class B
  def []
    "foo"
  end
end

 B.new[]
 => "foo" 
източник
Translate

Това е просто синтактична захар. Има определени синтаксисни модели, които се превръщат в изпращания на съобщения. По-специално

a + b

е същото като

a.+(b)

и същото важи за==, !=, <, >, <=, >=, <=>, ===, &, |, *, /, -, %, **, >>, <<, !==, =~и!~както добре.

Също,

!a

е същото като

a.!

и същото важи за~.

Тогава,

+a

е същото като

[email protected]

и същото важи за-.

Плюс това,

a.(b)

е същото като

a.call(b)

Има и специален синтаксис за сетери:

a.foo = b

е същото като

a.foo=(b)

И не на последно място, има специален синтаксис за индексиране:

a[b]

е същото като

a.[](b)

и

a[b] = c

е същото като

a.[]=(b, c)
източник
Translate

квадратните скоби са името на метода катоArray#sizeти имашArray#[]като метод и дори можете да го използвате като всеки друг метод:

array = [ 'a', 'b', 'c']
array.[](0) #=> 'a'
array.[] 1  #=> 'b'
array[2]    #=> 'c'

последният е нещо като синтактична захар и прави точно същото като първото. TheArray#+работа подобно:

array1 = [ 'a', 'b' ]
array2 = [ 'c', 'd' ]
array1.+(array2) #=> [ 'a', 'b', 'c', 'd' ]
array1.+ array2  #=> [ 'a', 'b', 'c', 'd' ]
array1 + array2  #=> [ 'a', 'b', 'c', 'd' ]

Можете дори да добавяте числа като това:

1.+(1) #=> 2
1.+ 1  #=> 2
1 + 1  #=> 2

същото работи с/, *, -и много други.

източник
Translate

Това е претоварващ оператор, той замества или допълва поведението на метод в клас, който сте дефинирали, или клас, чието поведение модифицирате. Можете да го направите на други оператори, различни от []. В този случай вие модифицирате поведението на [], когато той е извикан във всеки екземпляр на класа SongList.

Ако имате списък с песни = SongList.new и след това правите списък с песни ["foobar"], тогава вашият персонализиран деф ще влезе в действие и ще приеме, че "foobar" трябва да бъде предаден като параметър (ключ) и ще направи "foobar "каквото и да се казва в метода, трябва да се направи ключово.

Опитвам

class Overruler
    def [] (input)
          if input.instance_of?(String)
            puts "string"
          else
            puts "not string"
          end
     end
end
foo = Overruler.new
foo["bar"].inspect
foo[1].inspect
източник
Leave a Reply
You must be logged in to post a answer.
За автора