Gettery i settery dla tablicy w includowanym module

witam
mam modul powiedzmy Extensions ktory jest includowany do modelu powiedzmy Projects, jak moge dodac gettery i settery, ktorymi poslugiwał bym sie tak jakby model mial przypisany hash, czyli np

P = Project.new
p.moje[:cos] = “lala”
p.moje[:cos]

podejrzewam ze potrzebuje w module cos na ksztalt:

def moje << value

end

ale cos nie mogę wygoglowć składni

Nie wiem dokladnie co chcesz zrobic ani czy dobrze zrozumialem to co napisales

W zasadzie samemu sobie odpowiedziales na pytanie. Skoro hash by sie sprawdzil w tej sytuacji czemu go nie uzyc ?

[code=ruby]module Bar

def storage
@storage ||= {}
end

end

class Foo
include Bar
end

pry(main)> f = Foo.new
=> #Foo:0x0000000f5f2fd0

pry(main)> f.storage
=> {}

pry(main)> f.storage.object_id
=> 128918060

pry(main)> f.storage[:ala] = “ma kota”
=> “ma kota”

pry(main)> f.storage[:kot] = “ma ale”
=> “ma ale”

pry(main)> f.storage.object_id
=> 128918060

pry(main)> f.storage
=> {:ala=>“ma kota”, :kot=>“ma ale”}

pry(main)> f.storage[:kot]
=> “ma ale”[/code]
ps: Moglbys tez uzyc tego https://github.com/svenfuchs/hashr zamiast zwyklego Hash

konkretnie to chodzi o cos takiego ze pewne wartosci modelu trzymane sa w redis, sa to zserializowane hashe, dotychczas mam takie metody, ale chcialbym zeby to dzialalo jak tablica

def set_setting(key, value)
  $redis.hset "jakisklucz", key, value.to_json
end

def get_setting(key)
  $redis.hexists("jakisklucz", key) ? JSON.parse($redis.hget "jakisklucz", key) : nil
end

czyli chcialbym sie np. odwolac

p.settings[:color] = “red”
p.settings[:color]

module MyModule def [](key) end def []=(key,value) end end

nie bardzo rozumiem, bo to doda chyba mozliwosc ustawiania dowolnych kluczy i wartosci w modelu gdzie modul jest includowany, a ja chcialbym sie odwoływac tak jak wyzej napisałem o ile to możliwe

[code=ruby]class SettingsMixin
def initialize
@settings ||= {}
end

def
@settings.fetch key
end

def []=(key, value)
@settings.store key, value
end
end

module SettingsModule
def self.included(base)
base.class_eval do
def initialize
@settings = SettingsMixin.new
super
end

  attr_accessor :settings    
end

end
end

class Settings
include SettingsModule
end

setting = Settings.new

setting.settings[:key] = ‘value’
puts setting.settings[:key]
puts setting.settings[:no_key] #=> IndexError: key not found[/code]
pozmieniaj sobie po prostu metody [] i []= na to co tam musi być (nie używałem redis to nie wiem ;)) and you’re ready to go :smiley:

Dzięki, troche już to rozjaśniło, ale to jeszcze nie to. Działa gdy tworzę nowy obiekt Setting.new ale już dla istniejących Settings.last.setting zawsze jest nil. Jak można to wmiksować zeby działało dla wszystkich settings

Tzn.? Bo nie bardzo rozumiem. W takiej postaci jaką podałem to całkiem normalne zachowanie :wink: W końcu te ustawienia nigdzie się nie zapisują (to zwykły Hash). Tak jak mówiłem musisz pozmieniać [] i []= tak żeby pobierało/zapisywało z/do redis-a :wink:

Poza tym twój przykład nigdy nie zadziała (no chyba, że zdefiniujesz metodę last w klasie Settings). Jeśli już to: Settings.settings.last

może niezbyt czytelnie opisałem mój problem, ale dzieki Twoim wskazówkom doszedłem dokładnie do tego co chciałem, oto kod

[code=ruby]module Customizations

extend ActiveSupport::Concern

module InstanceMethods

def customizations
  @customizations||= CustomizationsMixin.new(redis_key)
end

def redis_key
  "customizations:%s:%s" % [self.class.name.tableize.singularize, self.id]
end

end

class CustomizationsMixin
def initialize(redis_key)
@redis_key = redis_key
end

def [](key)
  value = $redis.hexists(@redis_key, key) ? $redis.hget(@redis_key, key) : nil
  return nil unless value
  JSON.is_json?(value) ? JSON.parse(value) : value
end

def []=(key, value)
  new_value = (value.is_a?(Hash) || value.is_a?(Array)) ? value.to_json : value
  $redis.hset @redis_key, key, new_value
  $redis.bgsave
end

end

end[/code]
dzięki temu http://www.fakingfantastic.com/2010/09/20/concerning-yourself-with-active-support-concern/ modułowi kod takich rozszerzeń jest czytelniejszy

Pytałeś o składnię - więc pokazałem jak wygląda.