Kuinka [hakasulke] -menetelmän määrittely Rubyssa toimii?

Translate

Menen läpiRuby-ohjelmointi - käytännöllinen ohjelmoijan opasja törmännyt tähän koodinpalaan:

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

En ymmärrä miten [] -menetelmän määritteleminen toimii?

Miksi avain on [] ulkopuolella, mutta kun menetelmää kutsutaan, se on sisällä []?

Voiko avain olla ilman sulkeita?

Ymmärrän, että on olemassa paljon parempia tapoja kirjoittaa tämä, ja osaan kirjoittaa oman menetelmän, joka toimii, mutta tämä [] menetelmä vain hämmentää minua ... Jokainen apu on erittäin arvostettu, kiitos

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

Kaikki vastaukset

Translate

Rubiinimenetelmät, toisin kuin monet kielet, voivat sisältää joitain erikoismerkkejä. Yksi niistä on taulukon hakuteksti.

Jos ottaisit käyttöön oman hajautusluokan, jossa haluat noutaa kohteen hashista, haluat tehdä sen päinvastoin, voit tehdä seuraavaa:

class SillyHash < Hash

  def [](key)
    super.reverse
  end

end

Voit todistaa tämän kutsumalla hash seuraavasti:

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

Joten def [] määritteli menetelmän, jota käytetään, kun teetmy_array["key"]Muita menetelmiä, jotka saattavat näyttää sinulle oudolta, ovat:

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

Pelkästään selventämään a: n määritelmää[]menetelmä ei liity matriiseihin tai hajautuksiin. Ota seuraava (keksitty) esimerkki:

class B
  def []
    "foo"
  end
end

 B.new[]
 => "foo" 
Lähde
Translate

Se on vain syntaktista sokeria. On tiettyjä syntaksimalleja, jotka käännetään viestilähetyksiksi. Erityisesti

a + b

on sama kuin

a.+(b)

ja sama koskee==, !=, <, >, <=, >=, <=>, ===, &, |, *, /, -, %, **, >>, <<, !==, =~ja!~yhtä hyvin.

Myös,

!a

on sama kuin

a.!

ja sama koskee~.

Sitten,

+a

on sama kuin

[email protected]

ja sama koskee-.

Plus,

a.(b)

on sama kuin

a.call(b)

Setereille on myös erityinen syntakse:

a.foo = b

on sama kuin

a.foo=(b)

Ja viimeisenä mutta ei vähäisimpänä, indeksoinnissa on erityinen syntaksin:

a[b]

on sama kuin

a.[](b)

ja

a[b] = c

on sama kuin

a.[]=(b, c)
Lähde
Translate

hakasulkeet ovat menetelmän nimen kaltaisiaArray#sizesinulla onArray#[]menetelmänä ja voit jopa käyttää sitä kuten mitä tahansa muuta menetelmää:

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

viimeinen on jotain syntaktista sokeria ja tekee täsmälleen saman kuin ensimmäinen.Array#+toimi samankaltaisesti:

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

Voit jopa lisätä tällaisia numeroita:

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

sama toimii/, *, -ja paljon muuta.

Lähde
Translate

Se on käyttäjän ylikuormittaja, se ohittaa tai täydentää menetelmän käyttäytymistä määrittelemässäsi luokassa tai luokassa, jonka käyttäytymistä muokkaat. Voit tehdä sen muille operaattoreille, jotka eivät ole []. Tässä tapauksessa muokkaat []: n käyttäytymistä, kun sitä kutsutaan mihin tahansa luokan SongList-esiintymään.

Jos sinulla on kappalelista = SongList.new ja sitten teet kappalelistan ["foobar"], mukautettu def-toimintosi tulee toimintaan ja oletetaan, että "foobar" on välitettävä parametrina (avain) ja se toimii "foobar" "mitä tahansa menetelmän mukaan pitäisi tehdä avaimen.

Yrittää

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
Lähde
Leave a Reply
You must be logged in to post a answer.
Kirjailijasta