rubymotion-community / sugarcube

Some sugar for your cocoa. RubyMotion helpers.
Other
421 stars 66 forks source link

The sugarcube API #3

Closed radiospiel closed 12 years ago

radiospiel commented 12 years ago

Disclaimer: This all is my personal position; there is a lot of personal taste involved in what I write here. So when you read "foo should be bar" please understand it as "I think that foo should be bar". I would just like the Rubymotion community to build a framework which I would love to work with; and these are my 2 cent. I wrote a number of those things down in a post to the rubymotion google group; this one here is specifically on the sugarcube API.

a)

I do like the on(:event) methods, it reads great; but I do think, that the block should be able to receive the actual event. I do not like the off(:event) because code like the following feels a bit asymmetrical to me:

button.on(:touch) { my_code }
button.on(:touch) { my_other_code }

button.off(:touch)      # remove all handlers

I think the jQuery API has a lot to offer in how to attach event handlers and chain code and so on.

b) Symbol extensions

Symbol extensions are just, errm, not good. Why? Take this example:

:upside_down.uiorientation  # => UIDeviceOrientationPortraitUpsideDown

Conceptionally, "uiorientation" is not a property of a Symbol. (Or a string, for that matter.) And there is no specific naming scheme. Do you want to know the name of the uiorientation method? Why is it called :upside_down instead of :portrait_upside_down? One would have to guess.

I understand the idea of namespacing. If you take a careful look at UIKit constants, they are all namespaced, even if in a single identifier. They are properly linked in the UIKit documentation. And when using namespacing sugarcube should stick with what ruby offers in namespacing support, namely modules; i.e. System.uifont(30) instead of :system.uifont(30) (which I feel is still terrible)

c)

Conversions are cool. In a ruby spirit, they should be called .to_something instead of .something. Whether or not keep the ui-part of the name is probably a matter of taste; I myself would prefer .to_image instead of .to_uiimage, but could live with the ui one.

Conversions should fail early when they are not successful; "my_image".to_image should raise an exception if the image does not exist. (This is definitely controversial, as ruby's String#to_i, for example, just returns 0 if no part of the String can be converted; I could live very well with an additional bang-method .to_image!)

Conversions should still be conversions only and not a fancy way of calling some method. I.e.

"my_font".to_font(20) 

should not work. Why? Consider the documentation issue (i.e. b)). And where to stop: should the API provide

"my_font".to_font(20, :bold => true, :italic => true)

or should it be

"my_font".to_bold_font(20, :italic => true)

Should it support an additional "typeface" option?

d)

And is the end result more consise? This is the example from http://fusionbox.org/projects/rubymotion-sugarcube/. The 'plain' ruby version:

label = UILabel.alloc.init
label.frame = [[0, 0], [320, 40]]
label.font = UIFont.systemFontOfSize(30)
label.text = "I'm a pretty label."
label.alignment = UITextAlignmentCenter
label.textColor = UIColor.blueColor
view.addSubview(label)

label = UILabel.alloc.init
label.frame = [[40, 0], [320, 30]]
label.font = UIFont.fontWithName("Inconsolata", size:20)
label.text = "I'm a pretty label."
label.textColor = UIColor.colorWithRed(0.411765, green:0.411765, blue:0.411765, alpha:1.0)  # roughly 0x696969
view.addSubview(label)

image_up = UIImage.imageNamed 'pretty_image_up.png'
image_down = UIImage.imageNamed 'pretty_image_down.png'
ok_button = UIButton.buttonWithType(UIButtonTypeCustom)
button.setImage(image_up, forState:UIControlStateNormal)
button.setImage(image_down, forState:UIControlStateHighlighted)

This is quite hackable for anyone with a fleeting interest in UIKit. You guys instead insists "Oof, that’s a mouthful. You would hardly know it was Ruby!" and suggest instead:

label = UILabel.alloc.init
label.frame = [[0, 0], [320, 40]]
label.font = :system.uifont(30)
label.text = "I'm a pretty label."
label.alignment = :center.uialignment
label.textColor = :blue.uicolor
view << label

label = UILabel.alloc.init
label.frame = [[40, 0], [320, 30]]
label.font = "Inconsolata".uifont(20)
label.text = "I'm a pretty label."
label.textColor = :dimgray.uicolor  # 0x696969.uicolor also works!
view << label

image_up = 'pretty_image_up.png'.uiimage
image_down = 'pretty_image_down.png'.uiimage
ok_button = UIButton.buttonWithType(:custom.uibuttontype)
button.setImage(image_up, forState: :normal.uicontrolstate)
button.setImage(image_down, forState: :highlighted.uicontrolstate)

which has the same amount of code, but now I would loose control :(

Please take my words as some critical input to the project; I do acknowledge the effort you put into this. I would just want the framework you are building to be one I would love to work with; and these are my 2 cent.

/eno

colinta commented 12 years ago

hmm...

a) blocks can receive the event, I'll make sure there isn't a bug there that prevents that, and add it to the example.

what is the asymmetry? this is modeled after jQuery's on/off methods, and they look very similar.

   $('#el').on('mouseup mousedown', function(e) { console.log(e); });
   el.on(:mouseup, :mousedown) { |e| puts e }
radiospiel commented 12 years ago

On 05.06.2012, at 19:09, Colin Thomas-Arnold wrote:

hmm...

a)

blocks can receive the event, I'll make sure there isn't a bug there that prevents that, and add it to the example.

If they can, that's cool. The example in the README didn't show it, though; so I took it that it couldn't. My mistake, I am sorry.

what is the asymmetry? this is modeled after jQuery's on/off methods, and they look very similar.

the asymmetry is that there are two on-calls and one off-call. Don't you feel is asymmetric? That/If jQuery does the same does not make the asymmetry go away. But then, I personally didn't ever use off anyways; jQuery or otherwise.

Best regards, /eno

colinta commented 12 years ago

The rest of the arguments here are purely matters of taste, aka bike shedding.

My recommendation: you have a framework to write!

I'll make sure the event handling works as expected, I think the README is misleading when it says

The ability to remove some handlers is not supported right now

Either that's out of date, or I meant something else... I'm not sure.

The criticisms you offer, both here and on the googlegroup, are not really constructive if you haven't taken a second to use these tools, I hope that's not also the case with BubbleWrap. No one is asking you to use this stuff, but I for one am not really interested in writing things the way you propose. It's reminds me of the satyr/coco guy, who opened a bug on coffee script every time the syntax was a little off from how he wanted it.

Eventually he forked it, and wrote his own thing, and good for him! Though, the thing he made is an abomination - I hope that's not what you do!

colinta commented 12 years ago

There was a bug, but not related to this stuff. The block does get the event, I've updated the README.

radiospiel commented 12 years ago

Colin, be assured that I actually do use BubbleWrap, and tried to use sugarcube. And what I wrote here and in the group is a review of my experience and a suggestion of what I feel could be better. Just call it "community feedback". If you think you don't need it or want it, that is fine with me. Of course, there is much of taste matters. And you guys are entitled to a taste totally different from mine, who would I be to expect otherwise?

Anyways, godspeed to the sugarcube project.

PS: The comparison with some guy unknown to me goes down not very well, though. What's that to do with us, here?