2009-08-11 10 views
30

Nauka ruby. Jestem pod wrażeniem, że wartość logiczna atrybuty powinny być nazwane następująco:Ruby: Konwencja nazewnictwa atrybutów boolowskich i użycie

my_boolean_attribute? 

Jednak pojawiają się błędy składniowe, gdy próbuje wykonać następujące czynności: „?”

class MyClass 
    attr_accessor :my_boolean_attribute? 

    def initialize 
    :my_boolean_attribute? = false 
    end 
end 

Widocznie rubin jest nienawidząc . Czy to jest konwencja? Co ja robię źle?

Odpowiedz

40

Edytuj: trzy lata później; czasy, są one-changin' ...

Julik's answer jest najprostszym i najlepszym sposobem na rozwiązanie problemu tych dniach:

class Foo 
    attr_accessor :dead 
    alias_method :dead?, :dead # will pick up the reader method 
end 

Moja odpowiedź do oryginalnego pytanie wynika, dla potomnych ...


wersja krótka:

nie można użyć znaku zapytania w nazwie zmiennej instancji.

Dłuższa wersja:

Weźmy, na przykład, attr_accessor :foo - to prostu koncepcyjnie nieco cukru składniowej za:

def foo 
    @foo 
end 

def foo=(newfoo) 
    @foo = newfoo 
end 

Ponadto znak zapytania przyrostek jest przeważnie tylko konwencja wskazująca, że ​​wartość zwracana metody jest wartością logiczną.

Najlepszym przybliżeniem mogę zrobić tego, co masz zamiar tutaj ...

class MyClass 

    def initialize 
    @awesome = true 
    end 

    def awesome? 
    @awesome 
    end 

end 

W tym przypadku nie może być przypadek należy dokonać za korzystanie attr_accessor - Po tym wszystkim, może to być wyraźny, że pracujesz bezpośrednio z atrybutem boolean. Zazwyczaj zapisuję sufiks znaku zapytania, gdy wdrażam metodę, której boolowska wartość zwracana jest oparta na nieco bardziej złożonych warunkach niż wartość atrybutu.

Pozdrawiam!


Edit, dwa lata później, po niedawnym komentarzu:

  1. Ruby wymusza pewne konwencje nazewnictwa. Symbole w Ruby nie mogą mieć znaków zapytania. W związku z tym wywołania z obu komputerów będą kończyły się niepowodzeniem z NameError. Edycja: nieprawidłowa, po prostu użyj cytowanej składni dla symbolu, np. :"my_attribute?"
  2. Symbole są niezmienne, próba przypisania do jednego spowoduje wyświetlenie SyntaxError.
+6

Rubyist zwykle nie używa przedrostka is_ ani w nazwach zmiennych, ani w nazwach metod. Po prostu niesamowite? zamiast is_awesome? –

+0

Dobra uwaga, weppos. Zmieniono "is_", aby uniknąć mylnego potomka ;-) –

+0

Z tej odpowiedzi wynika, że ​​nie ma prawdziwej konwencji? :/ –

5

? jest konwencją dla nazw metod, a nie zmiennych. Nie można użyć zmiennej instancji o nazwie @foo?, jednak można użyć zmiennej o nazwie @foo i nazwę (ręcznie utworzoną) metodę pobierającą foo?, jeśli chcesz.

+0

hmm, więc attr_accessor pomocnik nie usunie "?" koniec dla mnie, huh. Cieszę się, że tak naprawdę nie jest to konwencja, na przykład vars. Myślałem, że zwariowałem. –

6

Symbol attr_accessor oznacza, że ​​nazwa zmiennej to @my_boolean_attribute, więc należy ją ustawić (nie symbol).

Nie można również użyć? dla zmiennych, tylko nazwy metod.

+0

ty dla symbolu catch. self.my_boolean_attribute będzie działać poprawnie? –

+0

Tak, powinno. –

+0

Och, pozwól mi dodać - tylko w metodach instancji. W zakresie klasy będzie szukać zmiennej klasy zasięgu (@@ my_boolean_attribute). Oczywiście nie muszę ci tego mówić, ale chciałem się upewnić, że to, co powiedziałem, jest poprawne pod względem technicznym. –

3

małpa-łatanie metaprogramming - może to może być bardziej elegancki, to tylko szybki projekt, a ja nie zrobiłem METAPROGRAMOWANIE na chwilę ...

# inject the convenience method into the definition of the Object class 
class Object 
    def Object::bool_attr(attrname) 
    class_eval { define_method(attrname.to_s, 
      lambda { instance_variable_get('@' + attrname.to_s.chop) }) } 
    class_eval { define_method(attrname.to_s.chop+"=", 
      lambda { |x| instance_variable_set('@'+attrname.to_s.chop, x) }) } 
    end 
end 

### somewhere later 

class MyClass 

    bool_attr :my_boolean_attribute? 

    def initialize 
    @my_boolean_attribute = true 
    end 
end 

# yet even more later 

foo = MyClass.new 
bar = MyClass.new 

foo.my_boolean_attribute = 1 
puts foo.my_boolean_attribute? 
puts bar.my_boolean_attribute? 

Dzięki takiemu podejściu , możesz być SUCHA i otrzymać też fajny znak zapytania. Być może trzeba będzie wybrać lepszą nazwę niż "bool_attr", np. "bool_attr_accessor" lub coś podobnego.

Definicje, które stworzyłem, są nieco zepsute, w tym sensie, że znak zapytania znajduje się w oryginalnym symbolu. Prawdopodobnie bardziej czystym podejściem byłoby uniknięcie znaku zapytania w nazwie symbolu i dołączenie go podczas definiowania metody - powinno być mniej mylące.

Aha, i prawie zapomniałem to obowiązkowy link: Seeing metaclasses clearly

+0

+1 za link! Prawdopodobnie nie doda w tym przypadku metody wygody, ponieważ nie jest to konwencja. Nie chcę mylić innych. Pomysły będą jednak szczęśliwie kanibalizowane przez inne problemy! –

+1

Jeśli utrzymujesz to w zespole, myślę, że tego typu pytania powinny być dyskutowane na przeglądach - w niektórych scenariuszach może to mieć sens, w niektórych przypadkach nie. Nie zakodowałem Rubiego w zespole, więc staram się stosować podejście, które daje mi najmniej LOC do patrzenia. –

+0

+1. Jeśli tylko dla meta-sprytu ... –

38

Najprostszym sposobem, aby szybko dodać "metodę pytanie" czy używać aliasing dla metody czytnika

class Foo 
    attr_accessor :dead 
    alias_method :dead?, :dead # will pick up the reader method 
end 
+0

niesamowite! Robiłem to długo. –

+0

Używając tego możesz użyć zarówno 'dead' jak i' dead? ', Prawda? Ale pozwala tylko na ustawienie przez "dead"? –

+3

Ustawienie pozostaje przez "dead =" – Julik

Powiązane problemy