How to implement a NSTabView delegate with MacRuby? - macruby

I try to set an NSTabView delegate using MacRuby with XCode, but I can't figure how to write the delegate. I use:
def intialize
#tab_changed.delegate = self
end
def tabViewdidSelectTabViewItem(a_notification)
puts "tab has changed"
end
Then in the .xib, I hook the NSTab view element with the class, but nothing happen when I select some tabs.
Usually the delegate are very easy to use, but this one has a syntax like this :
tabView:didSelectTabViewItem:
and I don't know how to write this in MacRuby. Should I use tabViewdidSelectTabViewItem or tabView_didSelectTabViewItem (none of them works).
Thanks for your help.

Assuming this is being done in a ViewController, instead of using initialize, better to do things the Cocoa way and use a method like viewDidLoad.
def viewDidLoad
#tab_changed.delegate = self
end
The signature for the delegate method you want is -(void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem. In MacRuby, that would be represented like this:
def tabView(tabView, didSelectTabViewItem: tabViewItem)
puts "tab has changed"
end

Related

Create a method that convert a List<SObject> to a Map<SObjectField, SObject> with SObjectField as method parameter, any suggestions?

global with sharing class test1 {
global Map<SObjectField, SObject> ConvertMap(List<SObject> listToConvert){
List<SObject> listToConvert = new List<SObject>;
Map<SObjectField, SObject> mapTest = new Map<SObjectField, SObject>;
mapTest.putAll(listToConvert);
return mapTest;
}
I've written this code, but it doesn't respect the request 'cause I can't put SObjectField as method parameter since the Map won't recognize the variable.
Does anyone have suggestions on how to do it?
Thank you in advance.
Do you really need SobjectField as map keys? the special class? If you're fine with strings as keys then there's a builtin, getPopulatedFieldsAsMap()
If you absolutely need SobjectField (I don't even know if it's serializable and can be passed to integrations, LWC etc)... You'd have to loop and marry the results to something like
Schema.describeSObjects(new List<String>{'Account'})[0].fields.getMap()

Odoo - Cannot loop through model records

I want to call a method every time my module gets installed or updated. Inside that method I want to loop through model records, but I'm only getting different errors.
This documentation looks pretty straightforward: https://www.odoo.com/documentation/9.0/reference/orm.html
But it doesn't work for me. I'm getting this error:
ParseError: "'account.tax' object has no attribute '_ids'" while parsing
This is how I call the method:
<openerp>
<data>
<function model="account.tax" name="_my_method" />
</data>
</openerp>
I took this from the first answer here: https://www.odoo.com/forum/help-1/question/how-can-i-execute-a-sql-statement-on-module-update-and-installation-6131
My model:
class my_account_tax(models.Model):
_name = 'account.tax'
_inherit = 'account.tax'
def _my_method(self, cr, uid, ids=None, context=None):
self.do_operation()
def do_operation(self):
print self
for record in self:
print record
It is basically a copy-paste from the docs. I only added method parameters cr, uid,.. If I take them away (and just leave 'self'), the error is a little different:
ParseError: "_my_method() takes exactly 1 argument (3 given)"
But also does not tell much.
use new api
#api.multi #if you use the new api you don't have to list all parameter in the function
def _my_method(self):
but you can keep it like that and do a pool on your model than loop throw the result that you get don't use self
if you use the new api use : self.env['model_name'].search([domain])

ruby Elegantly wrap an array of items each into an object

Given:
class Thing
def initialize(object)
#object = object
end
end
items = [1,2,3]
I'd like to know of a more elegant way to convert each item to the Thing than this:
items.map{ |item| Thing.new item }
# => [<Thing #object=1>, <Thing #object=2>, <Thing #object=3>]
You can use the unary prefix & operator:
items.map(&Thing.method(:new))
I have suggested that Classes should behave as Factory Functions, which would allow you to write it like this:
items.map(&Thing)
However, there doesn't seem to be much interest in the proposal. You can monkey-patch it yourself, though, the implementation is trivial:
class Class
def to_proc
method(:new).to_proc
end
end
I would argue that your example is perfectly fine. But perhaps you like something like this:
# in item.rb
def to_thing
Thing.new(self)
end
That would allow you to write:
items.map(&:to_thing)

Custom output with capistrano 3

I need to change output which is generated with sshkit formatters, and I can't install additional gems, but I can adjust my capistrano 3 configs. At first I tried just create new Formatter (I just copy paste pretty formatter, and made some output changes). like this https://gist.github.com/Dariusp/3e455fdb78b9f8636289
than set :format, :improvedformatter in deploy.rb file. And add
require_relative 'lib/improved_formatter'
to Capfile.
But I always get error "Abstract formatter should not be used directly, maybe you want SSHKit::Formatter::BlackHole", like I am trying use abstract formatter directly. if I try extend PrettyFormater, I get PrettyFormatter output, without my changes. It seems like always it execute parent class method. Its there any way how to create and set custom formatter in my capistrano configs ?
I ran into the exact same issue when I wanted to override the pretty formatter.
The problem was that I needed to also define the "<<" operator as this is defined as an alias in the base class and aliases are not inherited.
in deploy.rb:
set :format, :myformatter
in Capfile:
require 'lib/sshkit/formatters/myformatter'
in lib/sshkit/formatters/myformatter.rb:
module SSHKit
module Formatter
class MyFormatter < Pretty
def <<(obj)
write(obj)
end
def write(obj)
...
end
end
end
end

Idiomatic List Wrapper

In Google App Engine, I make lists of referenced properties much like this:
class Referenced(BaseModel):
name = db.StringProperty()
class Thing(BaseModel):
foo_keys = db.ListProperty(db.Key)
def __getattr__(self, attrname):
if attrname == 'foos':
return Referenced.get(self.foo_keys)
else:
return BaseModel.__getattr__(self, attrname)
This way, someone can have a Thing and say thing.foos and get something legitimate out of it. The problem comes when somebody says thing.foos.append(x). This will not save the added property because the underlying list of keys remains unchanged. So I quickly wrote this solution to make it easy to append keys to a list:
class KeyBackedList(list):
def __init__(self, key_class, key_list):
list.__init__(self, key_class.get(key_list))
self.key_class = key_class
self.key_list = key_list
def append(self, value):
self.key_list.append(value.key())
list.append(self, value)
class Thing(BaseModel):
foo_keys = db.ListProperty(db.Key)
def __getattr__(self, attrname):
if attrname == 'foos':
return KeyBackedList(Thing, self.foo_keys)
else:
return BaseModel.__getattr__(self, attrname)
This is great for proof-of-concept, in that it works exactly as expected when calling append. However, I would never give this to other people, since they might mutate the list in other ways (thing[1:9] = whatevs or thing.sort()). Sure, I could go define all the __setslice__ and whatnot, but that seems to leave me open for obnoxious bugs. However, that is the best solution I can come up with.
Is there a better way to do what I am trying to do (something in the Python library perhaps)? Or am I going about this the wrong way and trying to make things too smooth?
If you want to modify things like this, you shouldn't be changing __getattr__ on the model; instead, you should write a custom Property class.
As you've observed, though, creating a workable 'ReferenceListProperty' is difficult and involved, and there are many subtle edge cases. I would recommend sticking with the list of keys, and fetching the referenced entities in your code when needed.

Resources