X11 Xterm Keyboard layout is off by one or worse. - x11
I am running Xming on my local machine which is a windows box. I am connecting to Xming from an AIX box. I am connecting as root, because I need to perform a software installation with X11 windows. I am able to pull up xterm for example, and a X11 window pops up with Xterm, but the keyboard is all jacked up. Everything seems to be off by one or worse, and lots of other keys just flat out dont work such as the enter key. The xterm application isnt important, but every X11 window I open has this problem.
For example: A single press and release of the key:
--- row 1 ---
q = q
w = q
e = w
r = e
...
[ = p
] = [
\ = \
Enter = ]
--- row 2 ---
a = nothing
s = a
d = s
...
: = l
' = ;
--- row 3 ---
z = z
x = nothing
c = z
v = x
b = c
n = v
m = b
< = n
> = m
/ = ,
--- misc ---
space = space
tab = tab
` = '
1-9 = 1-9 (these are the only ones that are correct)
anything on the numpad = some variation of ^[[F (numpad 1 for example)
ctrl = \
alt = nothing
backspace = nothing
del = ^[[3~
esc = `
Here is the output of my setxkbmap -print
bash.root#myServer:/ # setxkbmap -print
Couldn't interpret _XKB_RULES_NAMES property
Use defaults: rules - 'xorg' model - 'pc101' layout - 'us'
xkb_keymap {
xkb_keycodes { include "xfree86+aliases(qwerty)" };
xkb_types { include "complete" };
xkb_compat { include "complete" };
xkb_symbols { include "pc+us" };
xkb_geometry { include "pc(pc101)" };
};
The error message
Couldn't interpret _XKB_RULES_NAMES property
tells you what the problem is: setxkbmap cannot find the configuration your X server is expecting, so it falls back (to a value which does not work for you). Xming's website has a trouble-shooting page which may help.
Related
wxPython ListBox event not firing
I have a wx.Dialog that contains a button and 2 ListBoxes, the button findAppBtn searches through a list of directories and then displays the result in actListBox. Selecting the directory of your choice from actListBox should then fire the event EVT_LISTBOX which calls actListBoxList. This function does an ls on the directory and should list the files it finds in the lower list box binListBox using Append. Upon selecting an item from the lower ListBox, the window closes. The problem is that the self.Bind(EVT_LISTBOX, self.actListBoxList) does not seem to be firing when an item is selected. (also please excuse the bad coding, I am trying to get it working before minifying) self.findAppBtn = wx.Button(panel, -1, "Find app") self.findAppBtn.SetDefault() self.Bind(wx.EVT_BUTTON, self.startConf, self.findAppBtn) hBox2.Add(self.findAppBtn, 0, flag=wx.LEFT, border=5) vBox.Add(hBox2, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP|wx.BOTTOM, border=3) self.actListBox = wx.ListBox(panel, choices=[]) self.Bind(wx.EVT_LISTBOX, self.actListBoxList) vBox.Add(self.actListBox, 2, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP|wx.BOTTOM, border=3) self.binListBox = wx.ListBox(panel, choices=[]) self.Bind(wx.EVT_LISTBOX, self.binListBoxList) vBox.Add(self.binListBox, 2, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP|wx.BOTTOM, border=3) self.closeBtn = wx.Button(panel, wx.ID_OK) hBox4.Add(self.closeBtn, 0, flag=wx.LEFT, border=5) vBox.Add(hBox4, 0, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.BOTTOM, border=5) panel.SetSizer(vBox) def startConf(self,e): val = self.cmdTxt.GetValue().replace(" ","\ ") path = "/private/" aCmd = "find " + path + " -iname '*"+val+"*.app'" try: s = pxssh.pxssh() s.login(sshIP, "root", sshPort, sshPass) s.sendline(aCmd) s.prompt() AP = s.before for m in AP.split('\n'): if path in m: self.actListBox.Append(m.replace(path,"").strip()) s.logout() return path except pxssh.ExceptionPxssh as e: self.parent.progressBox.AppendText(str(e)) def actListBoxList(self,e): #get string from top box selection e.g xxxx-xxxx-xxxx-/myapp.app selName = self.actListBox.GetStringSelection() path = "/private/" #list all the files in the dir from top box selection aCmd = "ls " + path + selName try: s = pxssh.pxssh() s.login(sshIP, "root", sshPort, sshPass) s.sendline(aCmd) s.prompt() ls = s.before for file in ls.split('\n'): if not file.endswith("/"): reg = r"\..*" matchObj = re.search(reg, file) if not matchObj: self.binListBox.Append(file) s.logout() except pxssh.ExceptionPxssh as e: self.parent.progressBox.AppendText(str(e)) def binListBoxList(self,e): binaryName = self.binListBox.GetStringSelection() self.Close() EDIT: self.actListBox.Bind(wx.EVT_LISTBOX, self.actListBoxList) fixed the issue.
calling self.Bind(... binds the event to the parent window which is why you're not seeing the event being called. Bind to the listbox instead: self.actListBox.Bind(wx.EVT_LISTBOX, self.actListBoxList)
Join tiles in Corona SDK into one word for a Breakout game grid?
I have a game project to re-implement Breakout. I want to display two words, each word on a line. They are joined by the bricks block. Inside, the top line is the first name, aligned left. The bottom line is the last name, aligned right. They are input from textboxes, and rendered as shown: Each second that passes, the screen will add a configurable number of bricks to the grid (for example, five bricks per second) until the two words appear complete. I displayed a letter of the alphabet which is created from the matrix(0,1). ...But I don’t know how to join them into one word. How can I join these letters? This is what I've gotten so far: Bricks.lua local Bricks = display.newGroup() -- static object local Events = require("Events") local Levels = require("Levels") local sound = require("Sound") local physics = require("physics") local Sprites = require("Sprites") local Func = require("Func") local brickSpriteData = { { name = "brick", frames = {Sprites.brick} }, { name = "brick2", frames = {Sprites.brick2} }, { name = "brick3", frames = {Sprites.brick3} }, } -- animation table local brickAnimations = {} Sprites:CreateAnimationTable { spriteData = brickSpriteData, animationTable = brickAnimations } -- get size from temp object for later use local tempBrick = display.newImage('red_apple_20.png',300,500) --local tempBrick = display.newImage('cheryGreen2.png',300,500) local brickSize = { width = tempBrick.width, height = tempBrick.height } --tempBrick:removeSelf( ) ---------------- -- Rubble -- needs to be moved to its own file ---------------- local rubbleSpriteData = { { name = "rubble1", frames = {Sprites.rubble1} }, { name = "rubble2", frames = {Sprites.rubble2} }, { name = "rubble3", frames = {Sprites.rubble3} }, { name = "rubble4", frames = {Sprites.rubble4} }, { name = "rubble5", frames = {Sprites.rubble5} }, } local rubbleAnimations = {} Sprites:CreateAnimationTable { spriteData = rubbleSpriteData, animationTable = rubbleAnimations } local totalBricksBroken = 0 -- used to track when level is complete local totalBricksAtStart = 0 -- contains all brick objects local bricks = {} local function CreateBrick(data) -- random brick sprite local obj = display.newImage('red_apple_20.png') local objGreen = display.newImage('cheryGreen2.png') obj.name = "brick" obj.x = data.x --or display.contentCenterX obj.y = data.y --or 1000 obj.brickType = data.brickType or 1 obj.index = data.index function obj:Break() totalBricksBroken = totalBricksBroken + 1 bricks[self.index] = nil obj:removeSelf( ) sound.play(sound.breakBrick) end function obj:Update() if(self == nil) then return end if(self.y > display.contentHeight - 20) then obj:Break() end end if(obj.brickType ==1) then physics.addBody( obj, "static", {friction=0.5, bounce=0.5 } ) elseif(obj.brickType == 2) then physics.addBody( objGreen,"static",{friction=0.2, bounce=0.5, density = 1 } ) end return obj end local currentLevel = testLevel -- create level from bricks defined in an object -- this allows for levels to be designed local function CreateBricksFromTable(level) totalBricksAtStart = 0 local activeBricksCount = 0 for yi=1, #level.bricks do for xi=1, #level.bricks[yi] do -- create brick? if(level.bricks[yi][xi] > 0) then local xPos local yPos if(level.align == "center") then --1100-((99*16)*0.5) xPos = display.contentCenterX- ((level.columns * brickSize.width) * 0.5/3) + ((xi-1) * level.xSpace)--display.contentCenterX --xPos = 300 +(xi * level.xSpace) yPos = 100 + (yi * level.ySpace)--100 else xPos = level.xStart + (xi * level.xSpace) yPos = level.yStart + (yi * level.ySpace) end local brickData = { x = xPos, y = yPos, brickType = level.bricks[yi][xi], index = activeBricksCount+1 } bricks[activeBricksCount+1] = CreateBrick(brickData) activeBricksCount = activeBricksCount + 1 end end end totalBricks = activeBricksCount totalBricksAtStart = activeBricksCount end -- create bricks for level --> set from above functions, change function to change brick build type local CreateAllBricks = CreateBricksFromTable -- called by a timer so I can pass arguments to CreateAllBricks local function CreateAllBricksTimerCall() CreateAllBricks(Levels.currentLevel) end -- remove all brick objects from memory local function ClearBricks() for i=1, #bricks do bricks[i] = nil end end -- stuff run on enterFrame event function Bricks:Update() -- update individual bricks if(totalBricksAtStart > 0) then for i=1, totalBricksAtStart do -- brick exists? if(bricks[i]) then bricks[i]:Update() end end end -- is level over? if(totalBricksBroken == totalBricks) then Events.allBricksBroken:Dispatch() end end ---------------- -- Events ---------------- function Bricks:allBricksBroken(event) -- cleanup bricks ClearBricks() local t = timer.performWithDelay( 1000, CreateAllBricksTimerCall) --CreateAllBricks() totalBricksBroken = 0 -- play happy sound for player to enjoy sound.play(sound.win) print("You Win!") end Events.allBricksBroken:AddObject(Bricks) CreateAllBricks(Levels.currentLevel) return Bricks Levels.lua local Events = require("Events") local Levels = {} local function MakeLevel(data) local level = {} level.xStart = data.xStart or 100 level.yStart = data.yStart or 100 level.xSpace = data.xSpace or 23 level.ySpace = data.ySpace or 23 level.align = data.align or "center" level.columns = data.columns or #data.bricks[1] level.bricks = data.bricks --> required return level end Levels.test4 = MakeLevel { bricks = { {0,2,0,0,2,0,0,2,0}, {0,0,2,0,2,0,2,0,0}, {0,0,0,0,2,0,0,0,0}, {1,1,2,1,1,1,2,1,1}, {0,0,0,0,1,0,0,0,0}, {0,0,0,0,1,0,0,0,0}, {0,0,0,0,1,0,0,0,0}, } } Levels.test5 = MakeLevel { bricks = { {0,0,0,1,0,0,0,0}, {0,0,1,0,1,0,0,0}, {0,0,1,0,1,0,0,0}, {0,1,0,0,0,1,0,0}, {0,1,1,1,1,1,0,0}, {1,0,0,0,0,0,1,0}, {1,0,0,0,0,0,1,0}, {1,0,0,0,0,0,1,0}, {1,0,0,0,0,0,1,0} } } -- Levels.test6 = MakeLevel2 -- { -- bricks = -- { ----A "a" = {{0,0,0,1,0,0,0,0}, -- {0,0,1,0,1,0,0,0}, -- {0,0,1,0,1,0,0,0}, -- {0,1,0,0,0,1,0,0}, -- {0,1,1,1,1,1,0,0}, -- {1,0,0,0,0,0,1,0}, -- {1,0,0,0,0,0,1,0}, -- {1,0,0,0,0,0,1,0}, -- {1,0,0,0,0,0,1,0}}, ----B -- "b" = {{1,1,1,1,0,0,0}, -- {1,0,0,0,1,0,0}, -- {1,0,0,0,1,0,0}, -- {1,0,0,0,1,0,0}, -- {1,1,1,1,0,0,0}, -- {1,0,0,0,1,0,0}, -- {1,0,0,0,0,1,0}, -- {1,0,0,0,0,1,0}, -- {1,1,1,1,1,0,0}}, --........... --....... --... -- --Z -- "z"= {{1,1,1,1,1,1,1,0}, -- {0,0,0,0,0,1,0,0}, -- {0,0,0,0,1,0,0,0}, -- {0,0,0,0,1,0,0,0}, -- {0,0,0,1,0,0,0,0}, -- {0,0,1,0,0,0,0,0}, -- {0,0,1,0,0,0,0,0}, -- {0,1,0,0,0,0,0,0}, -- {1,1,1,1,1,1,1,0}} -- } -- } -- stores all levels in ordered table so that one can be selected randomly by index Levels.levels = { --Levels.test4, Levels.test5 -- Levels.test6, } function Levels:GetRandomLevel() return self.levels[math.random(#Levels.levels)] end Levels.notPlayedYet = {} Levels.currentLevel = Levels:GetRandomLevel() -- Events function Levels:allBricksBroken(event) self.currentLevel = Levels:GetRandomLevel() end Events.allBricksBroken:AddObject(Levels) return Levels The work I've done thus far (same as above) as an external download: http://www.mediafire.com/download/1t89ftkbznkn184/Breakout2.rar
In the interest of actually answering the question: I'm not 100% sure what you mean by "How can I join these letters", but from poking through the code I have a guess, so please clarify on whether it is accurate, or if I am wrong about what you wanted. Scenario 1 You haven't successfully achieved the image illustrated in the screenshot - you've been able to draw one letter, but not multiple ones. In this case, you'll need to have a better understanding of what your code is doing. The CreateBricksFromTable function takes in a Level object, which is created by the MakeLevel function from a table with a bricks property, which is a table of tables that represent rows with columns in them, showing what type of brick should be at each position. In your commented-out level, you have created an table where the bricks field contains a field for each letter, but the MakeLevel function still expects a bricks field that directly contains the grid of blocks. You will have to - as it seems you attempted - create a MakeWordLevel function (or the like) that takes this letter list, and a word for each line, and constructs a larger grid by copying the appropriate letters into it. StackOverflow is not your programming tutor, and an SO question is not the right forum for having people write code for you or getting into step-by-step details of how to do this, but I'll leave you a basic outline. Your function would look something like this: local function MakeWordLevel(data, line1, line2) local level = {} ... return level end And then would have to: Populate all of the same properties that MakeLevel does Calculate how wide (level.columns) the level should be with all the letters Create a table in the same format as the bricks properties, but big enough to hold all of the letters Go through the input strings (line1 and line2), find the correct letter data from what is now the test6 array, and copy that data into the large table Assign that table as level.bricks This question already is a bit outside of what StackOverflow is intended for in that it asks about how to implement a feature rather than achieve a small, specific programming task, so any further followup should take place in a chatroom - perhaps the Hello World room would be helpful. Scenario 2: This was my original guess, but after considering and reading past edits, I doubt this is answering the right question You may want a solid "background" of, say, red blocks, surrounding your letters and making the field into a solid "wall", with the name in a different color. And you may want these bricks to slowly show up a few at a time. In that case, the main thing you need to do is keep track of what spaces are "taken" by the name bricks. There are many ways to do this, but I would start with a matrix to keep track of that - as big as the final playing field - full of 0's. Then, as you add the bricks for the name, set a 1 at the x,y location in that matrix according to that block's coordinate. When you want to fill in the background, each time you go to add a block at a coordinate, check that "taken" matrix before trying to add a block - if it's taken (1), then just skip it and move onto the next coordinate. This works if you're filling in the background blocks sequentially (say, left to right, top to bottom), or if you want to add them randomly. With random, you'd also want to keep updating the "taken" matrix so you don't try to add a block twice. The random fill-in, however, presents its own problem - it will keep taking longer to fill in as it goes, because it'll find more and more "taken" blocks and have to pick a new one. There are solutions to this, of course, but I won't go too far down that road when I don't know if that's even what you want.
I don't really understand (or read, for that matter) your code but from what I see joining them into complete words is easy. You have two possibilities. You can "render" them directly into your level/display data, simply copy them to the appropriate places, like this: -- The level data. local level = {} -- Create the level data. for row = 1, 25, 1 do local rowData = {} for column = 1, 80, 1 do rowData[column] = "." end level[row] = rowData end -- Now let us setup the letters. local letters = { A = { {".",".",".","#",".",".",".","."}, {".",".","#",".","#",".",".","."}, {".",".","#",".","#",".",".","."}, {".","#",".",".",".","#",".","."}, {".","#","#","#","#","#",".","."}, {"#",".",".",".",".",".","#","."}, {"#",".",".",".",".",".","#","."}, {"#",".",".",".",".",".","#","."}, {"#",".",".",".",".",".","#","."} }, B = { {"#","#","#","#",".",".","."}, {"#",".",".",".","#",".","."}, {"#",".",".",".","#",".","."}, {"#",".",".",".","#",".","."}, {"#","#","#","#",".",".","."}, {"#",".",".",".","#",".","."}, {"#",".",".",".",".","#","."}, {"#",".",".",".",".","#","."}, {"#","#","#","#","#",".","."} } } -- The string to print. local text = "ABBA" -- Let us insert the data into the level data. for index = 1, #text, 1 do local char = string.sub(text, index, index) local charData = letters[char] local offset = index * 7 for row = 1, 9, 1 do local rowData = charData[row] for column = 1, 7, 1 do level[row][offset + column] = rowData[column] end end end -- Print everything for row = 1, 25, 1 do local rowData = level[row] for column = 1, 80, 1 do io.write(rowData[column]) end print() end You save you letters in a lookup table and then copy them, piece by piece, to the level data. Here I replaced the numbers with dots and number signs to make it prettier on the command line. Alternately to that you can also "render" the words into a prepared buffer and then insert that into the level data by using the same logic.
While debugging the function breakpoint is not hit
I am using powerbuilder 11.2 and I have a pbl that creates a main screen. The user enters an order number in the textbox and hit enter and it fills in data in the bottom of the screen. I am trying to get debugging to hit a breakpoint in my function but it seems to ignore the breakpoint. Is there a way to break into the function? I have a variable I need to evaluate and I can't seem to get into the function while running. Here is the code: Decimal{2} ld_total_hrs,ld_load_hrs,ld_unload_hrs long ll_stops_rowcount, ll_row, ll_type, ll_ord_number, ll_rd_rowcount datetime ldt_1st_stop, ldt_last_stop, ldt_start_time, ldt_end_time, ldt_deliver_time string ls_dest_id, ls_type, ls_pay_id, ls_ref_number, ls_pay_leg_config boolean lb_first_drop = TRUE ld_load_hrs = 0 ld_unload_hrs = 0 SetNull(ldt_deliver_time) ll_stops_rowcount = dw_trip.RowCount() If ll_stops_rowcount < 1 then Return 0 For ll_row = 1 to ll_stops_rowcount If ll_row = 1 then ldt_1st_stop = dw_trip.GetItemDateTime ( 1, "stops_stp_arrivaldate" ) End if If dw_trip.GetItemString(ll_row,"stops_stp_type") = "PUP" then ldt_start_time = dw_trip.GetItemDateTime(ll_row,"stops_stp_arrivaldate") ldt_end_time = dw_trip.GetItemDateTime(ll_row,"stops_stp_departuredate") ld_load_hrs = ld_load_hrs + (f_datetimediff(ldt_start_time,ldt_end_time)/60)/60 End if If dw_trip.GetItemString(ll_row,"stops_stp_type") = "DRP" then ldt_start_time = dw_trip.GetItemDateTime(ll_row,"stops_stp_arrivaldate") ldt_end_time = dw_trip.GetItemDateTime(ll_row,"stops_stp_departuredate") ld_unload_hrs = ld_unload_hrs + (f_datetimediff(ldt_start_time,ldt_end_time)/60)/60 // get the first drops info for the report if paylegaslane is true else get last drop ls_pay_leg_config = is_PayLegConfig If is_CompanyOverride=true then ls_pay_leg_config = "ByLeg" End if //TGRIFFIT - PayLegConfig = 'ByLeg' in TMW is equivalent to 'PayLegAsLane = 'Y' in FSS if Upper(ls_pay_leg_config) = 'BYLEG' then If lb_first_drop Then ldt_deliver_time = ldt_end_time ls_dest_id = dw_trip.GetItemString(ll_row,"stops_cmp_id") ls_ref_number = dw_trip.GetItemString(ll_row,"stops_stp_refnum") lb_first_drop = FALSE End if else ldt_deliver_time = ldt_end_time ls_dest_id = dw_trip.GetItemString(ll_row,"stops_cmp_id") ls_ref_number = dw_trip.GetItemString(ll_row,"stops_stp_refnum") end if End if Next ldt_last_stop = dw_trip.GetItemDateTime ( ll_stops_rowcount, "stops_stp_departuredate" ) ld_total_hrs = (f_datetimediff(ldt_1st_stop,ldt_last_stop)/60)/60 ll_ord_number = long(dw_triptab.GetItemString(1,"ord_number")) //If g_messlevel% < 1 Then if gnv_app.ii_MessLevel < 1 Then ids_revdist.Reset() End if //Load the datastore that stores all the revenue distribution values ll_rd_rowcount = ids_revdist.RowCount() ids_revdist.InsertRow(0) ll_rd_rowcount ++ ids_revdist.SetItem(ll_rd_rowcount,"mov_number",i_movenum%) ids_revdist.SetItem(ll_rd_rowcount,"lgh_number",dw_trip.GetItemNumber(1,"stops_lgh_number")) ids_revdist.SetItem(ll_rd_rowcount,"total_hours",ld_total_hrs) ids_revdist.SetItem(ll_rd_rowcount,"load_hours",ld_load_hrs) ids_revdist.SetItem(ll_rd_rowcount,"unload_hours",ld_unload_hrs) ids_revdist.SetItem(ll_rd_rowcount,"deliver_date",ldt_deliver_time) ids_revdist.SetItem(ll_rd_rowcount,"dest_code",ls_dest_id) ids_revdist.SetItem(ll_rd_rowcount,"ref_number",ls_ref_number) Return ids_revdist.RowCount() I need to evaluate this line specifically and I set a breakpoint at this line: ls_pay_leg_config = "ByLeg" as well as the following lines. It does not break. I am rusty at PowerBuilder and can figure this out.
Put the breakpoint at the start of the loop.
Ruby multi-line regex
I have a ruby multi-line string (called efixes) that looks like: ID STATE LABEL INSTALL TIME UPDATED BY ABSTRACT === ===== ========== ================= ========== ====================================== 1 S hayo32.02 xxxxxxx xxxxxxxx xxxxxxxxxxxxxxx 2 S 23434.23 xxxxxxx xxxxxxxx xxxxxxxxxxxxxxx STATE codes: S = STABLE M = MOUNTED U = UNMOUNTED Q = REBOOT REQUIRED B = BROKEN I = INSTALLING R = REMOVING T = TESTED P = PATCHED N = NOT PATCHED SP = STABLE + PATCHED SN = STABLE + NOT PATCHED QP = BOOT IMAGE MODIFIED + PATCHED QN = BOOT IMAGE MODIFIED + NOT PATCHED RQ = REMOVING + REBOOT REQUIRED I only want to display the lines that start with a number. I am having trouble, it doesn't seem to be matching. I found this solution here, (that I don't truly understand right now): efixes_array = efixes.split("\n").select{|x| /\A[0-9]/.match(x)} io.puts efixes_array.collect{|x| x.scan(/\A[0-9]/)}.flatten It is only matching the numbers. I want to display the entire line. The end result, I want to display what is under the "LABELS" column.
This line from your example code efixes.split("\n").select{|x| /\A[0-9]/.match(x)} returns an array with all lines that start with a number.
Perl to Ruby conversion (multidimensional arrays)
I'm just trying to get my head around a multidimensional array creation from a perl script i'm currently converting to Ruby, I have 0 experience in Perl, as in i opened my first Perl script this morning. Here is the original loop: my $tl = {}; for my $zoom ($zoommin..$zoommax) { my $txmin = lon2tilex($lonmin, $zoom); my $txmax = lon2tilex($lonmax, $zoom); # Note that y=0 is near lat=+85.0511 and y=max is near # lat=-85.0511, so lat2tiley is monotonically decreasing. my $tymin = lat2tiley($latmax, $zoom); my $tymax = lat2tiley($latmin, $zoom); my $ntx = $txmax - $txmin + 1; my $nty = $tymax - $tymin + 1; printf "Schedule %d (%d x %d) tiles for zoom level %d for download ...\n", $ntx*$nty, $ntx, $nty, $zoom unless $opt{quiet}; $tl->{$zoom} = []; for my $tx ($txmin..$txmax) { for my $ty ($tymin..$tymax) { push #{$tl->{$zoom}}, { xyz => [ $tx, $ty, $zoom ] }; } } } and what i have so far in Ruby: tl = [] for zoom in zoommin..zoommax txmin = cm.tiles.xtile(lonmin,zoom) txmax = cm.tiles.xtile(lonmax,zoom) tymin = cm.tiles.ytile(latmax,zoom) tymax = cm.tiles.ytile(latmin,zoom) ntx = txmax - txmin + 1 nty = tymax - tymin + 1 tl[zoom] = [] for tx in txmin..txmax for ty in tymin..tymax tl[zoom] << xyz = [tx,ty,zoom] puts tl end end end The part i'm unsure of is nested right at the root of the loops, push #{$tl->{$zoom}},{ xyz => [ $tx, $ty, $zoom ] }; I'm sure this will be very simple for a seasoned Perl programmer, thanks! `
The Perl code is building up a complex data structure in $tl -- hash, array, hash, array: $tl{$zoom}[i]{xyz}[j] = $tx # j = 0 $tl{$zoom}[i]{xyz}[j] = $ty # j = 1 $tl{$zoom}[i]{xyz}[j] = $zoom # j = 2 So I think the key line in your Ruby code should be like this: tl[zoom] << { 'xzy' => [tx,ty,zoom] } Note also that the root item ($tl) refers to a hash in the Perl code, while your Ruby code initializes it to be an array. That difference might cause problems for you, depending on the values that $zoom takes.